我们在项目中使用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上看到数据库在重新启动应用程序后消失了。
在我的Visual Studio上的Xamarin配置中检查在部署之间保留设备上的应用程序数据/缓存是否为真,我的
BlobCache.ApplicationName = "AppName";
在OnStar Method
任何人都知道发生了什么?感谢
答案 0 :(得分:3)
我最近碰到了这个,对我而言是因为我错过了这个文件 https://github.com/akavache/Akavache/blob/master/src/Akavache.Sqlite3/content/AkavacheSqliteLinkerOverride.cs.pp
如果有其他人遇到这个问题,我首先建议你做OP所做的事并创建自己的。最后哪个更好,但是如果你想使用静态的,那么确保有一个看起来像
的类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缓存。这就是重启时数据消失的原因
答案 1 :(得分:1)
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);
我的CacheConfig:
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;
}
此解决方案基于其他线程。
此致
答案 2 :(得分:0)
我的猜测是,因为你正在中间停止进程“如果我停止调试会话”,你就不会关闭缓存然后丢失一些数据。
答案 3 :(得分:0)
只是猜测,但也许你的Salvar
方法正在抛出(可能login
无法序列化)?你不会真的知道这是因为你没有等待它。你不能因为它返回void
而不是Task
。这是一种不好的做法,应尽可能避免。
更改Salvar
以返回Task
,并确保await
保存。
答案 4 :(得分:0)
您的问题是使用“本地计算机”
Xamarin.iOS 可能会删除存储在BlobCache.LocalMachine中的数据以释放磁盘空间(仅当您的应用未运行时)。位置BlobCache.UserAccount和BlobCache.Secure将备份到iCloud和iTunes。
如果系统磁盘空间不足,Xamarin.Android 也可能会开始删除存储在BlobCache.LocalMachine中的数据。尚未明确指定在系统清理过程中您的应用是否可以运行。
有四个内置位置在某些系统上应用了一些魔术:
BlobCache.LocalMachine -缓存的数据。此数据可能会被删除,恕不另行通知。
BlobCache.UserAccount -用户设置。一些系统将这些数据备份到云中。
BlobCache.Secure -用于保存敏感数据(例如凭据)。
BlobCache.InMemory -保存在内存中的数据库。数据在应用程序的生命周期内存储。
您宁愿使用
public async void Salvar(Login login)
{
await BlobCache.UserAccount.InsertObject("login", login);
}
[参考:Akavache文档]