缓存设置
ApolloClient所使用的所有缓存的ApolloClient
必须符合NormalizedCache
协议。此协议提供了以序列化的键值对形式存在的标准化缓存条目,称为Records
。
除了由Apollo iOS提供的默认缓存实现外,您还可以创建自己的缓存,提供您喜欢的任何自定义存储实现。因为提供给您的NormalizedCache
实现中的记录已经由“标准化”了,您可以将注意力集中在标准化缓存数据的存储上。
如果您有兴趣创建自定义 NormalizedCache
实现,首先请阅读 《NormalizedCache API 参考》。
Apollo iOS 包含两种类型的 NormalizedCache
默认实现:
InMemoryNormalizedCache
这是 ApolloClient 默认使用的缓存实现。
内存缓存会将缓存结果直接存储在程序运行时的系统内存中。结果不会持久化到磁盘。这意味着当应用程序终止时,缓存不会被保存。
由于缓存数据直接存储在内存中,读写记录比基于磁盘的缓存实现速度快。
内存缓存最适合缓存短期数据。对于预期经常更改或将来不太可能再次访问的数据,建议使用内存缓存。
以下是一些例子
- 新闻源中的条目
- 基于位置的数据
- 特定搜索词的搜索结果
对于短期数据,每个应用程序运行开始时有清晰的缓存,加上改进的性能,这可能使 InMemoryNormalizedCache
变成一个不错的选择。
ⓘ 注意
InMemoryNormalizedCache
没有实现任何自动淘汰策略。这意味着您的应用程序负责响应任何内存不足通知,并采取清除缓存或移除选定记录的措施。
设置
要使用 InMemoryNormalizedCache
,无需任何额外操作!
InMemoryNormalizedCache
是初始化 ApolloClient
的默认缓存。如果想在未经修改的情况下使用内存缓存,只需创建一个不传递任何自定义 ApolloStore
到 store
参数的 ApolloClient
实例即可。
如果您需要自行实例化内存缓存,可以使用一行代码完成
let cache = InMemoryNormalizedCache()
SQLiteNormalizedCache
SQLite缓存将缓存结果写入到磁盘上的SQLite
文件。
将缓存结果存储在磁盘上,允许我们在应用程序运行之间维护缓存。然而,每次缓存操作所需的文件I/O可能会略微增加缓存响应时间。
此外,因为这个缓存不保留内存中的任何结果,所以没有缓存使用过多内存的风险。
磁盘上的缓存最佳于缓存持久数据。它适用于不期望像访问那么频繁变化的数据;花费很长时间检索的数据;或需要在离线状态下访问的数据。
以下是一些例子
- 用户设置/个人资料
- 本地创建的用户内容
- 后台抓取的数据
对于您希望在应用程序运行之间持久化的数据,SQLiteNormalizedCache
可能满足您的需求。
ⓘ 注意
在将缓存数据持久化到磁盘时,请确保任何敏感数据都不是写入到缓存中。缓存数据以纯文本格式存储,并可从设备中检索。您可能需要清理您的缓存数据或对缓存文件进行加密。
设置
要使用SQLiteNormalizedCache
,您需要将ApolloSQLite
子包添加到您的项目中,使用您的首选包管理工具:
一旦将ApolloSQLite
链接到您的项目,您可以执行以下操作:
- 为您的
SQLite
文件设置一个文件URL。 - 使用该文件URL实例化一个
SQLiteNormalizedCache
。 - 使用您的
SQLiteNormalizedCache
实例化一个ApolloStore
。 - 将此
ApolloStore
传递到ApolloClient
的初始化器:
// 1. Determine where you would like to store your SQLite file.// A commonly used location is the user's Documents directory// within your application's sandbox.let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true).first!let documentsURL = URL(fileURLWithPath: documentsPath)let sqliteFileURL = documentsURL.appendingPathComponent("test_apollo_db.sqlite")// 2. Use that file URL to instantiate the SQLite cache:let sqliteCache = try SQLiteNormalizedCache(fileURL: sqliteFileURL)// 3. And then instantiate an instance of `ApolloStore` with the cache you've just created:let store = ApolloStore(cache: sqliteCache)// 4. Assuming you've set up your `networkTransport` instance elsewhere,// pass the store you just created into your `ApolloClient` initializer.let apolloClient = ApolloClient(networkTransport: networkTransport, store: store)