自动更新

一个简单的面向协议的框架,用于编写易于更新的,数据驱动的视图。

通讯协定

我使用的协议叫做Unit因为我制作的游戏涉及战争内容。

模型协议

 protocol Unit { var name: String { get set } var id: String { get } var status: UnitStatus { get set } } 

我还需要能够等同于它们。

 func ==(lhs: Unit?, rhs: Unit?) -> Bool { return (lhs?.id == rhs?.id) } 

现在,我将创建一个简单的struct以符合我的Unit协议。

 struct Hero: Unit { var id: String var name: String var status: UnitStatus } 

查看协议

接下来是我用于显示Unit视图协议。 这将令人震惊地称为UnitView

 protocol UnitView { var unit: Unit? { get } func prepare(withUnit unit: Unit?) } 

我可以在协议中添加任何内容,但是魔术发生在prepare(withUnit unit: Unit?) 。 我将所有视图更新代码都放在了prepare(withUnit unit: Unit?) ,我很高兴。

我需要扩展UnitView协议(您也可以执行UIViewControllers),以便可以调用autoUpdate() ,这使视图成为数据存储更新的观察者。

 extension UnitView where Self: UIView { func autoUpdate() { NotificationCenter.default.addObserver(forName: NSNotification.Name.objectUpdated, object: nil, queue: OperationQueue.main) { [weak self] (notification: Notification) in guard let unit = notification.userInfo?["unit"] as? Unit else { return } if self?.unit == unit { self?.unit = unit self?.prepare(withUnit: unit) } } } } 

在视图初始化中调用autoUpdate()函数后,视图(或视图控制器)将自行更新。

这是一个符合UnitView可以自动更新的UICollectionViewCell的示例。

 class UnitCollectionViewCell: UICollectionViewCell, UnitView { var unit: Unit? @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var statusLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() autoUpdate() } func prepare(withUnit unit: Unit?) { self.nameLabel.text = unit?.name self.statusLabel.text = unit?.face() } override func prepareForReuse() { super.prepareForReuse() prepare(withUnit: unit) } } 

数据存储

自动更新框架的另一个关键组件是一个数据存储,用于向我们的UnitView发送通知。

这就是我需要的简单数据存储。

 class DataStore { static let shared = DataStore() func update(object: Unit?) { guard let updatedUnit = object else { return } // save the object in whatever way you need to // notifies our UnitViews that a Unit was updated NotificationCenter.default.post(name: NSNotification.Name.objectUpdated, object: nil, userInfo: [Constants.objectKey: updatedUnit]) } } 

图表

👍