10

我正在使用(并且喜欢)Siesta 与我的 Swift 应用程序中的 REST Web 服务进行通信。我已经实现了一系列 ResponseTransformers 来将 API 调用响应映射到模型类,以便 Siesta 资源自动解析为对象实例。这一切都很好。

我现在想实现一个 Siesta PersistantCache 对象来支持离线模式,方法是让 Siesta 将这些对象缓存到磁盘(而不是内存中),方法是将它们存储在 Realm 中。我不确定如何执行此操作,因为文档说(关于 EntityCache.writeEntity 函数):

这种方法可以——而且应该——检查实体的内容和/或标题,如果它不可编码,则忽略它。虽然它们可以应用基于类型的规则,但是,缓存实现不应应用基于资源或基于url 的规则;用于Resource.configure(...)选择缓存哪些资源以及由谁缓存。

为了符合本指南,我在服务配置期间根据 URL 模式匹配为每种资源类型创建了一个特定的 PersistentCache 对象:

class _GFSFAPI: Service {
    private init() {
        configure("/Challenge/*") { $0.config.persistentCache = SiestaRealmChallengeCache() }
    }

但是,由于 EntityCache 协议方法仅包含对实体的引用(它公开原始内容但不公开类型化对象),我看不出在调用 EntityCache.writeEntity 期间如何调用领域写入方法或如何拉在 EntityCache.readEntity 期间离开领域的对象。

任何有关如何解决此问题的建议将不胜感激。

4

1 回答 1

8

很好的问题。为每个模型单独EntityCache实现当然可以,尽管创建所有这些小粘合类似乎很麻烦。

缓存中的模型

writeEntity()的调用与所有响应转换器结束时出现的任何内容一起调用。如果您的转换器配置为吐出模型类,则writeEntity()查看模型。如果这些模型是对领域友好的模型,那么,我看不出有什么理由你不能只调用realm.add(entity.content). (如果这给您带来问题,请通过更新问题告诉我。)

相反,当从缓存中读取时,readEntity()返回的内容不会再次通过转换器管道,因此它应该返回与转换器产生的完全相同的内容,即模型。

缓存查找键

您从文档中引用的特定段落写得不好,可能有点误导。当它说你“不应该应用基于资源或基于 url 的规则”时,它实际上只是试图劝阻你不要解析forKey:参数——这只是一个秘密的 URL,但应该对缓存实现保持不透明。但是,您可以从给定实体收集的任何信息都是公平的游戏,包括entity.content.

当前 API 下的一个问题——这是一个严重的问题——是您需要保留从 Siesta 的密钥(您应该将其视为不透明的)到不同类型的 Realm 对象的映射。您可以通过以下方式做到这一点:

  1. 保持一个 Realm 模型,专门用于保持从 Siesta 缓存键到各种类型的 Realm 对象的多态映射,
  2. 通过添加siestaKey属性并跨模型进行某种联合查询,或者
  3. 通过在 Realm 之外保留(缓存键)→(模型类型,模型 ID)映射。

我可能会按此顺序选择选项,但我相信您在这里使用 Realm 作为EntityCache. 确定选项后,我鼓励您提交 Github 问题以获取任何建议的 API 改进。

于 2015-11-08T00:15:46.620 回答