IOS 上的 Akavache 损失信息
Akavache loss information on IOS
我们在项目中使用 Akavache,在 Android 中一切正常,但在 iOS 中我们遇到了一些问题,如果我们像这样在缓存中保存键值:
public async void Salvar(Login login)
{
await BlobCache.LocalMachine.InsertObject("login", login);
}
BlobCache 将保存无误,如果我停止调试会话,并重新开始调试并尝试使用以下方法获取值:
public async Task<Login> Recuperar()
{
try
{
var dados = await BlobCache.LocalMachine.GetObject<Login>("login");
return dados;
}
catch (KeyNotFoundException)
{
return null;
}
}
我会得到 KeyNotFoundException,我不知道为什么在 Android 中工作得很好但是在 iOS 上似乎数据库在重新启动应用程序后消失了。
在我的 Xamarin 配置中 Visual Studio 检查部署之间设备上的保留应用程序 data/cache 是真实的,我的
BlobCache.ApplicationName = "AppName";
在 OnStar 方法
有人知道发生了什么事吗?谢谢
我的猜测是,由于您在中间停止了进程“如果我停止调试会话”,您不会关闭缓存然后丢失一些数据。
只是猜测,但也许您的 Salvar
方法正在抛出(也许 login
无法序列化)?你不会真的知道那是因为你没有等待它。你不可能是因为它 returning void
而不是 Task
。这是应尽可能避免的不良做法。
将Salvar
更改为returnTask
并确保await
保存。
终于解决了!问题是Akavache正在使用的路径,创建我自己的路径后问题就解决了。
1 - 创建一个 DependencyService 以获取您的运行时平台路径,例如 iOS:
var documentsPath =Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libraryPath = Path.Combine(documentsPath, "..", "Library");
var path = Path.Combine(libraryPath, "cache.db");
在你的 PCL 初始化中你这样做:
BlobCache.ApplicationName = "AppName";
BlobCache.EnsureInitialized();
var local = DependencyService.Get<ILocalCache>();
var pathToCacheDbFile = local.GetPath();
CacheConfig.NormalCache = new SQLitePersistentBlobCache(pathToCacheDbFile);
我的缓存配置:
public class CacheConfig
{
public static bool Initialised { get; set; }
public static IBlobCache NormalCache { get; set; }
}
然后你像这样使用你所有的缓存:
public async Task<bool> Salvar(Login login)
{
try
{
await CacheConfig.NormalCache.InsertObject("login", login);
}
catch (Exception ex)
{
//todo
}
return true;
}
此解决方案基于此处的其他线程。
此致
我最近 运行 喜欢这个,对我来说是因为我丢失了这个文件
https://github.com/akavache/Akavache/blob/master/src/Akavache.Sqlite3/content/AkavacheSqliteLinkerOverride.cs.pp
如果其他人遇到这个问题,我首先建议您按照 OP 的做法创建您自己的问题。最后那更好,但是如果你想使用静态的,那么确保有一个看起来像
的 class
using System;
using Akavache.Sqlite3;
// Note: This class file is *required* for iOS to work correctly, and is
// also a good idea for Android if you enable "Link All Assemblies".
namespace SomeNameSpace
{
[Preserve]
public static class LinkerPreserve
{
static LinkerPreserve()
{
throw new Exception(typeof(SQLitePersistentBlobCache).FullName);
}
}
public class PreserveAttribute : Attribute
{
}
}
发生的事情是弹性缓存永远不会被换入,默认情况下它只使用 InMemory 缓存。这就是数据在重启时消失的原因
你的问题是使用“本地机器”
Xamarin.iOS 可能会删除存储在 BlobCache.LocalMachine 中的数据,以释放磁盘 space(仅当您的应用不是 运行).位置 BlobCache.UserAccount 和 BlobCache.Secure 将备份到 iCloud 和 iTunes。
Xamarin.Android 也可能会开始删除存储在 BlobCache.LocalMachine 中的数据,如果系统用完磁盘 space。没有明确指定您的应用程序是否可以在系统清理时 运行。
有四个内置位置在某些系统上应用了一些魔法:
BlobCache.LocalMachine - 缓存数据。此数据可能会在不通知的情况下被删除。
BlobCache.UserAccount - 用户设置。一些系统将这些数据备份到云端。
BlobCache.Secure - 用于保存敏感数据 - 如凭据。
BlobCache.InMemory - 保存在内存中的数据库。数据在应用程序的生命周期内存储。
你应该使用
public async void Salvar(Login login)
{
await BlobCache.UserAccount.InsertObject("login", login);
}
[参考:Akavache 文档]
我们在项目中使用 Akavache,在 Android 中一切正常,但在 iOS 中我们遇到了一些问题,如果我们像这样在缓存中保存键值:
public async void Salvar(Login login)
{
await BlobCache.LocalMachine.InsertObject("login", login);
}
BlobCache 将保存无误,如果我停止调试会话,并重新开始调试并尝试使用以下方法获取值:
public async Task<Login> Recuperar()
{
try
{
var dados = await BlobCache.LocalMachine.GetObject<Login>("login");
return dados;
}
catch (KeyNotFoundException)
{
return null;
}
}
我会得到 KeyNotFoundException,我不知道为什么在 Android 中工作得很好但是在 iOS 上似乎数据库在重新启动应用程序后消失了。
在我的 Xamarin 配置中 Visual Studio 检查部署之间设备上的保留应用程序 data/cache 是真实的,我的
BlobCache.ApplicationName = "AppName";
在 OnStar 方法
有人知道发生了什么事吗?谢谢
我的猜测是,由于您在中间停止了进程“如果我停止调试会话”,您不会关闭缓存然后丢失一些数据。
只是猜测,但也许您的 Salvar
方法正在抛出(也许 login
无法序列化)?你不会真的知道那是因为你没有等待它。你不可能是因为它 returning void
而不是 Task
。这是应尽可能避免的不良做法。
将Salvar
更改为returnTask
并确保await
保存。
终于解决了!问题是Akavache正在使用的路径,创建我自己的路径后问题就解决了。
1 - 创建一个 DependencyService 以获取您的运行时平台路径,例如 iOS:
var documentsPath =Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libraryPath = Path.Combine(documentsPath, "..", "Library");
var path = Path.Combine(libraryPath, "cache.db");
在你的 PCL 初始化中你这样做:
BlobCache.ApplicationName = "AppName";
BlobCache.EnsureInitialized();
var local = DependencyService.Get<ILocalCache>();
var pathToCacheDbFile = local.GetPath();
CacheConfig.NormalCache = new SQLitePersistentBlobCache(pathToCacheDbFile);
我的缓存配置:
public class CacheConfig
{
public static bool Initialised { get; set; }
public static IBlobCache NormalCache { get; set; }
}
然后你像这样使用你所有的缓存:
public async Task<bool> Salvar(Login login)
{
try
{
await CacheConfig.NormalCache.InsertObject("login", login);
}
catch (Exception ex)
{
//todo
}
return true;
}
此解决方案基于此处的其他线程。
此致
我最近 运行 喜欢这个,对我来说是因为我丢失了这个文件 https://github.com/akavache/Akavache/blob/master/src/Akavache.Sqlite3/content/AkavacheSqliteLinkerOverride.cs.pp
如果其他人遇到这个问题,我首先建议您按照 OP 的做法创建您自己的问题。最后那更好,但是如果你想使用静态的,那么确保有一个看起来像
的 classusing System;
using Akavache.Sqlite3;
// Note: This class file is *required* for iOS to work correctly, and is
// also a good idea for Android if you enable "Link All Assemblies".
namespace SomeNameSpace
{
[Preserve]
public static class LinkerPreserve
{
static LinkerPreserve()
{
throw new Exception(typeof(SQLitePersistentBlobCache).FullName);
}
}
public class PreserveAttribute : Attribute
{
}
}
发生的事情是弹性缓存永远不会被换入,默认情况下它只使用 InMemory 缓存。这就是数据在重启时消失的原因
你的问题是使用“本地机器”
Xamarin.iOS 可能会删除存储在 BlobCache.LocalMachine 中的数据,以释放磁盘 space(仅当您的应用不是 运行).位置 BlobCache.UserAccount 和 BlobCache.Secure 将备份到 iCloud 和 iTunes。
Xamarin.Android 也可能会开始删除存储在 BlobCache.LocalMachine 中的数据,如果系统用完磁盘 space。没有明确指定您的应用程序是否可以在系统清理时 运行。
有四个内置位置在某些系统上应用了一些魔法:
BlobCache.LocalMachine - 缓存数据。此数据可能会在不通知的情况下被删除。
BlobCache.UserAccount - 用户设置。一些系统将这些数据备份到云端。
BlobCache.Secure - 用于保存敏感数据 - 如凭据。
BlobCache.InMemory - 保存在内存中的数据库。数据在应用程序的生命周期内存储。
你应该使用
public async void Salvar(Login login)
{
await BlobCache.UserAccount.InsertObject("login", login);
}
[参考:Akavache 文档]