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 方法

有人知道发生了什么事吗?谢谢

我的猜测是,由于您在中间停止了进程“如果我停止调试会话”,您不会关闭缓存然后丢失一些数据。

看这里:https://github.com/akavache/Akavache#shutting-down

只是猜测,但也许您的 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 文档]