【问题标题】:Akavache loss information on IOSIOS 上的 Akavache 丢失信息
【发布时间】:2017-01-11 13:04:18
【问题描述】:

我们在项目中使用 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 配置中,检查 Preserve application data/cache on device between deploys 是真的,我的

BlobCache.ApplicationName = "AppName"; 

OnStar 方法

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

【问题讨论】:

    标签: xamarin.ios xamarin.forms akavache


    【解决方案1】:

    我最近遇到了这个问题,对我来说这是因为我丢失了这个文件 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 缓存。这就是为什么数据在重启时消失的原因

    【讨论】:

      【解决方案2】:

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

      此解决方案基于此处的其他线程。

      问候

      【讨论】:

      • 您在哪里找到 Akavache 实际使用的路径?
      • @Guilherme 谢谢,这行得通。您能否修复您的解决方案所基于的链接。
      • 只是想知道使用自定义路径是否可以解决“可能会在不通知的情况下删除以节省空间”的问题?
      【解决方案3】:

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

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

      【讨论】:

      • Giusepe 在 InsertObject 之后我输入了这段代码:BlobCache.Shutdown().Wait();强制关机,但问题仍然存在。我认为问题不属于关机...谢谢
      【解决方案4】:

      只是猜测,但也许您的Salvar 方法正在抛出(可能login 无法序列化)?你不会真的知道这是因为你没有在等待它。你不能因为它返回void 而不是Task。这是一种不好的做法,应尽可能避免。

      Salvar 更改为返回Task 并确保await 保存。

      【讨论】:

      • Kent 我试过了,不幸的是没有用,我认为这是 Akavache 的问题。
      【解决方案5】:

      您的问题是使用“本地机器”

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-20
        • 2016-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多