关于IOS的Akavache丢失信息

时间:2017-01-11 13:04:19

标签: xamarin.ios xamarin.forms 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上看到数据库在重新启动应用程序后消失了。

在我的Visual Studio上的Xamarin配置中检查在部署之间保留设备上的应用程序数据/缓存是否为真,我的

BlobCache.ApplicationName = "AppName"; 
在OnStar Method

任何人都知道发生了什么?感谢

5 个答案:

答案 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)

终于解决了!问题是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);

我的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)

我的猜测是,因为你正在中间停止进程“如果我停止调试会话”,你就不会关闭缓存然后丢失一些数据。

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

答案 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文档]