增强混合应用程序中本地存储的弹性

时间:2019-01-23 18:04:46

标签: ios sqlite hybrid-mobile-app indexeddb

我已经开发了一款混合移动应用程序,已经在IOS,Android和Chrome上运行了5年以上。我的应用程序使用indexedDB数据库维护应用程序的状态并在两次重启之间保存它,但是在某些情况下,IOS可以清除indexedDB,尤其是在客户端设备内存不足的情况下。

基于对IOS不会任意决定的期望,我希望获得一些帮助,以帮助如何使用IOS设备上的本机SQL数据库维护indexedDB的并行副本,从而提高应用程序的弹性。清除属于该应用程序的内部SQL数据库。

我了解如何在Objective C和Javascript之间双向交流,但是我对Objective C的了解却不是最模糊的:

  1. 在应用文件系统中创建一个SQL数据库
  2. 选择将SQL数据库放置在应用文件系统中的位置
  3. 如何将新的键值对写入数据库
  4. 覆盖数据库中的现有键值对
  5. 从数据库中读取所有键值对(我希望实际上最多可以有1000个键值对),并将它们有效地传递回javascript代码。
  6. 清除数据库,然后重新启动。

任何有关如何实现此示例或更好的仍编码示例的有用资源的指针,将不胜感激。

我想补充一点,我没有使用Cordova或任何其他类似的应用程序开发环境,因此请不要建议将SQLite插件作为更大环境的一部分。我已经达到了使用定制编码方法的目的,并且我希望保持这种方式。

1 个答案:

答案 0 :(得分:0)

我已经探索了将每个indexedDB保存与写入IOS App Documents文件夹中的文件并行化的想法,希望与Caches文件夹相比,这种擦除的可能性较小。

在每个indexedDB setItem之后加上键值对,我将请求传递给Objective-C IOS应用程序代码,以在使用App Documents文件夹创建的子文件夹中创建一个文本文件,名称为“ key” .txt并将内容设置为值。

在每个indexedDB removeItem之后,我将一个请求传递给Objective-C IOS应用程序代码,以删除相应的文本文件'key'.txt。

在每个indexedDB clearAll之后,我删除上面创建的整个子文件夹。

现在,当应用程序启动并发现一个空的localForage数据库时,我将一个请求传递给Objective-C IOS应用程序代码,以测试带有关键项目的子文件夹是否存在。

如果不是,则这是该应用程序的全新安装,在这种情况下,将继续正常运行。

如果是,则表明indexedDB数据库已被删除。

在这种情况下,通过检查上面创建的文件夹的内容并剥离.txt位,并且在IOS Simulator忽略DS_Store的情况下,我请求Objective-C IOS应用程序代码返回键集。文件。

然后我一个接一个地请求每个密钥文件的内容,并将它们加载回以前为空的localForage数据库中,完成后,我可以继续进行,就好像它尚未被删除一样。

我发现有必要在javascript中使用零持续时间的超时,然后再请求每个值,以防止恢复大型数据库时调用堆栈超出错误。

这种方法似乎可行,我可以随时使用Safari Developer Resources选项卡操作清除数据库,然后手动重新启动应用程序,以进行测试。使用相同的选项卡,您可以看到indexedDB数据库正在重新填充。

由于数据库的大小,我实际上创建了一组不同类型的密钥的子文件夹,以便我可以选择还原数据库项目的顺序,尤其是当我的应用程序经常恢复使用时在位置发生重大变化之后的背景中,在这种情况下,对应用程序执行恢复的时间设置了最大时间限制。当然,这种改进是可选的,只有大型数据库才需要。

以下注释适用于想要尝试这种方法并假定在XCode 10.1中使用Objective C的任何人

  1. 使用NSHomeDirectory()和stringByAppendingPathComponent @“ Documents”来获取Documents文件夹。
  2. 使用stringByAppendingPathComponent为keys子文件夹创建一个子文件夹路径。
  3. 使用fileExistsAtPath检查keys子文件夹是否已经存在
  4. 如果不使用,请使用createDirectoryAtPath。
  5. 在indexedDB中保存或更改项目时,请使用stringByAppendingPathComponent创建密钥文件名路径,例如Base.txt的“ Base”键。
  6. 使用fileHandleforWritingAtPath来获取文件的fileHandle
  7. 如果fileHandle不存在,则需要使用writeToFile创建它来创建“密钥”文件
  8. 如果fileHandle存在,则truncateFileAtOffseyt:0(重要)以将其清除,然后使用writeData创建“密钥”文件的新版本。
  9. 在以上两种方法中均指定UTF8编码。
  10. 从indexedDB中删除项目时,请执行相同操作以获取密钥文件路径,然后使用removeItemAtPath。
  11. 可以通过使用removeItemAtPath删除整个子文件夹来清除设备。
  12. 还原过程使用contentsOfDirectoryAtPath来读取子文件夹中的密钥集。
  13. 每个项目的还原过程使用stringWithContentsOfFile读取数据文件,并使用对stringByEvaluatingJavaScriptFromString的调用返回用引号引起来的内容

希望这会有所帮助。