NSBundle 中预加载内容的 iOS 存储问题以及来自 API 的增量更新
Posted
技术标签:
【中文标题】NSBundle 中预加载内容的 iOS 存储问题以及来自 API 的增量更新【英文标题】:iOS storage issues with preloaded content in NSBundle and delta updates from API 【发布时间】:2014-02-18 09:51:13 【问题描述】:我目前正在开发一些存在类似问题的应用程序。我将尝试通过详细说明我过去所做的事情以及为什么这不是一个好的解决方案来解释它。
假设我有一个应用程序,其中包含地点列表和这些地点的一些照片。当客户首次安装应用程序时,应加载所有地点和照片并准备好离线使用。但是,如果通过在线 CMS 更改内容,则应用应下载新数据并加载(如果应用在线)。
目前的工作方式是 CMS 生成一个包含图像的 zip 文件,并将所有数据的完整转储为 txt 文件中的 JSON。 API 允许您指定时间戳,这意味着 zip 将仅包含从该日期修改/添加的数据。在将应用程序上传到 App Store 之前,我会下载完整的 zip 文件(时间戳 = 0)并将其存储在应用程序包中。首次运行应用程序时,将 zip 从 [NSBundle mainBundle] 复制到 Documents 目录,解压缩,将 JSON 导入 CoreData/SQLite,然后删除 zip。接下来,检查内部时间戳并进行 API 调用(如果在线)以查看是否有任何新内容;如果有,则会生成、下载、解压缩、导入、删除包含更改的新 zip 文件。
这种方法的问题是存储的数据多于应有的数据。如果初始 zip 为 300MB,则客户在安装后必须有大约 600MB 的免费空间(这是一个仅限 wifi 的大型下载),以便复制 zip 并解压缩内容。在第一次运行之后,您的所有解压缩数据占用了大约 310MB,但您不再需要的 300MB 被困在捆绑包中。同样,任何下载都必须有 2 倍的空间(1x 用于 zip 文件,1x 用于解压缩文件)。这只是暂时的(因为您将删除 zip),但仍然不理想。
我能看到的唯一解决方案是将所有初始资产存储在捆绑包中,而不是存储在 zip 文件中。导入的 JSON 将指定这些资产中的每一个都是捆绑资产,因此在加载图像时,从那里获取它们。如果没有设置该标志,它应该从 Documents 目录中获取它们(因为它们已经被下载)。不过,这并不能解决下载 zip 更新文件的问题。任何解决方案都必须以某种方式包含捆绑应用程序中的初始内容(尽管这使其超过 100MB OTA 限制),因为我希望客户能够立即使用该应用程序而无需更新内部数据库;没有人愿意下载一个应用程序,然后等待 5 分钟让它下载一个巨大的更新。
有人有更好的主意吗?我很想知道其他开发者是如何在他们的应用中执行这项任务的。
【问题讨论】:
【参考方案1】:我假设您的大部分内容是图像 + 文字。是否有可能保留一个紧凑的索引文件,该文件将为您的应用程序中的任何搜索查询提供动力,并能够确定要显示特定项目需要哪些内容?当您想使用 ZIP 文件中的数据时,有选择地提取所需的文件以显示该项目 - 用访问时间和计算能力换取磁盘空间。 (Objective-Zip 应该支持提取单个文件)
如果有帮助,可以将 ZIP 文件拆分为多个 ZIP 文件以加快选择性提取速度。进行此类细分的能力在很大程度上取决于内容的结构以及查询/访问内容的方式。
关于更新过程,如果问题是:
提取所需空间:如何将下载的 zip 文件拆分为多个单独的文件?在更新过程中:下载块1,提取块1,下载块2..(下载+提取前一个块可能并行发生,一般会加快更新过程)
提取后需要的空间:将初始建议也纳入更新 ZIP 文件。
显然,当您增加独立 ZIP 文件的数量时,与单个 ZIP 文件相比,您的压缩效果会降低。
我希望这至少能激发一些新想法。
【讨论】:
我忘记了可以进行选择性提取,因此这可以用于更新过程。对于初始数据加载,将所有资产捆绑在应用程序中可能更有效(zip 不会对图像进行太多压缩),但对于更新,我可以使用选择性 zip,直到完成更多百分比,此时提取所有内容并删除初始 zip 文件变得更便宜。谢谢!以上是关于NSBundle 中预加载内容的 iOS 存储问题以及来自 API 的增量更新的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 Interface Builder 中预加载 WKWebView?