Uniform
目的
Uniform 是一个维护内存中对象一致性的框架。
动机
对象一致性是一个重要的考虑因素,尤其是在用户界面的方面。保持内存中的对象及其填充的视图的最新状态,确保用户在整个应用程序的导航过程中都能获得一致的用户体验。
考虑以下情况:
-
用户关注了另一名用户。当他们导航回到自己的资料时,他们期望他们的关注数增加一个。
-
用户从播放器中喜欢了一个视频。如果用户关闭播放器并返回到他们打开播放器的视频列表,他们期望列表中的视频已被喜欢。
-
用户手动刷新视频列表,列表中的一个视频的标题自上次请求以来已更改。如果该视频位于另一个标签上的列表中,用户会期望该列表中的视频标题也得到更新。
Uniform 通过以安全和简单的方式维护对象状态,提供了一种使这些体验得以实现的方法。
文档
两部分
制服实际上是两种机制的组合:使对象能够相互合并,并跟踪对象所有者。
可合并对象
关注一致性的对象需要遵守《ConsistentObject》协议。此协议定义了一些通过名称获取和设置属性的要求。这些应当相对简单实现,并且可以轻松生成。使用此接口,协议通过启用单个对象更新另一个对象或一组对象更新的合并功能进行了扩展。
有两种方式可以与另一个对象更新。
同步
// For a single object
object = object.updated(with: otherObject)
// For a collection of objects
objects = objects.updated(with: otherObject)
异步
// For a single object
object.updated(with: otherObject, in: self) { (updatedObject) in
object = updatedObject
}
// For a collection of objects
objects.updated(with: otherObject, in: self) { (updatedObjects) in
objects = updatedObjects
}
所有这些函数都会执行深层次合并。这意味着对象和它的任何嵌套对象将与另一个对象及其嵌套对象合并,保证完美状态一致性。
对象所有者注册
为了使更新能在应用中传播,必须维护对象所有者的注册表。这由《ConsistencyManager》处理。此对象,很可能用作单例,跟踪拥有《ConsistentObject》的所有人。《ConsistentObject》所有者需要遵守《ConsistentEnvironment》。此协议定义了由《ConsistencyManager》用于推送和拉取对象的接口。《ConsistencyManager》拥有的《ConsistentEnvironment》聚合集合像一个始终最新的分布式对象存储。这允许Uniform无需额外内存。
为了注册到《ConsistencyManager》,必须调用ConsistentEnvironment
ConsistencyManager.shared.register(self)
《ConsistencyManager》只对每个ConsistentEnvironment
保留弱引用,因此无需注销。
对象一致性
通过组合上述两种机制,可以在整个应用中实现对象一致性。《ConsistencyManager》提供了以下API来利用此系统。
推送API
当对象更新时,无论是由于网络响应还是本地更新,都需要将它们推送到一致性管理器
。
// For a single object
ConsistencyManager.shared.pushUpdatedObject(object)
// For a collection of objects
ConsistencyManager.shared.pushUpdatedObjects(objects)
这将使用协议中所需的功能,将每个新对象推送到每个注册的一致性环境
。然后,一致性环境
负责使用一致性对象
合并函数将新对象合并到其拥有的任何对象中。
以下是一个一致性环境
的示例
class ProfileViewController: UIViewController
{
@IBOutlet weak var label: UILabel!
private var user: User
{
didSet
{
self.label.text = self.user.name
}
}
override func viewDidLoad()
{
super.viewDidLoad()
ConsistencyManager.shared.register(self)
}
}
// MARK: Object Consistency
extension ProfileViewController: ConsistentEnvironment
{
var objects: [ConsistentObject]
{
return [self.user]
}
func update(with object: ConsistentObject)
{
self.user = self.user.updated(with: object)
}
}
由于合并考虑了嵌套对象,即使更新的对象与现有对象类型不同,它仍然可能使用更新对象的某些部分进行更新。例如,如果现有对象是视频,更新的对象是频道,当用户具有相同的标识符时,视频可能使用频道的用户属性更新其用户属性。
拉取API
拉取API可以用来从一致性环境
检索对象或对象集合的最新版本。
// For a single object
ConsistencyManager.shared.pullUpdatedObject(for: object)
// For a collection of objects
ConsistencyManager.shared.pullUpdatedObjects(for: objects)
这些函数指导一致性管理器
遍历每个注册的一致性环境
中的对象,并对指定的对象执行任何必要的更新,确保其是最新的。
这可以用于我们有潜在过时对象的情况。例如,如果我们正在从网络缓存请求对象,我们可能希望在使用之前使用这些函数来更新它们,然后将它们返回给请求者。这样,本地发生的变化已包括在返回的对象中。
示例
要运行示例项目,请首先从GitHub克隆仓库,然后从示例目录运行pod install
。
最低要求
- Swift 4.1
安装
Uniform 通过 CocoaPods 提供。要安装,只需将以下行添加到您的 Podfile 中
pod 'Uniform'
作者
Gavin King, [email protected]
许可证
Uniform 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。