因为搬瓦工App需要缓存的数据量很小,所以使用UserDefaults来缓存数据。昨天在TG群里有用户提出能否实现iCloud跨设备的数据同步,这在有多个设备时非常有必要。于是花了点时间研究了一下iCloud相关的API,结果发现实现难度比我想象的要简单很多。

iCloud提供了以下三种不同类型的API:

下面看Key-value storage,API很简单,几乎都在NSUbiquitousKeyValueStore里,看文档就知道如何使用了。这里重点说一下使用时需要注意的地方:

0. 需要加入苹果开发者计划,也就是付费的开发者账号

这是必要条件。

1. 在Xcode里打开iCloud选项,如下图:

WX20181112-234805

注意勾选Key-value storage,一旦勾选会自动在项目中生成iCloud entitlements文件。

2. 监听数据变化的Notification

因为需要与其它设备进行数据同步,当数据在其它地方改变后,需要能收到通知。示例代码如下:

override func viewDidLoad() {
    super.viewDidLoad()

    let keyStore = NSUbiquitousKeyValueStore.default
    if let stringValue = keyStore.string(forKey: "MyString") {
        textField.text = stringValue
    }

    NotificationCenter.default.addObserver(self,
         selector: #selector(
              ViewController.ubiquitousKeyValueStoreDidChange),
        name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
        object: keyStore)
}

至此,NSUbiquitousKeyValueStore的集成就算完成了,存储时,只需要将原来的UserDefaults.standard改成NSUbiquitousKeyValueStore.default就可以了,因为API设计是一样的。

另外,苹果的文档里有提到,离线时应该使用UserDefaults,而不是NSUbiquitousKeyValueStore.default,但根据我的使用来看,离线似乎也没有什么问题。

Avoid using this class for data that is essential to your app’s behavior when offline; instead, store such data directly into the local user defaults database.