Sammcb
Sammcb

Reputation: 125

NSUbiquitousKeyValueStore taking too long for initial sync

I want to use NSUbiquitousKeyValueStore to store in iCloud some simple key-value pairs for a game I am making. I was under the impression that if the user deleted and then reinstalled the game, their progress would be restored when the app launched.

This appears not to be the case. From the testing I have done, the key-value pairs take a long time to get downloaded from iCloud upon the first launch of the app. After that, the data seems to get uploaded and downloaded almost instantly. This causes issues for my app because when it is reinstalled, it does not immediately have the users previous data and creates a new set of data, negating the point of using NSUbiquitousKeyValueStore.

Is there a way to ensure that information from NSUbiquitousKeyValueStore is available as soon as possible after the app is first launched, and if not what other iCloud APIs could I use?

Upvotes: 1

Views: 546

Answers (1)

byaruhaf
byaruhaf

Reputation: 4733

To ensure that information from NSUbiquitousKeyValueStore is available as soon as possible after the app is first launched. You need to do two steps.

  • Step 1:- Register for the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification during app launch.

  • Step 2:- Call the Instance Method
    NSUbiquitousKeyValueStore.default.synchronize() The recommended time to call this method is upon app launch, or upon returning to the foreground.

For Example:-

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ubiquitousKeyValueStoreDidChange), name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, object: NSUbiquitousKeyValueStore.default)
    NSUbiquitousKeyValueStore.default.synchronize()
    // referesh and retrieve keys 
}

@objc func ubiquitousKeyValueStoreDidChange(notification:Notification) {
// Get the reason for keys changed
    let changeReason = notification.userInfo![NSUbiquitousKeyValueStoreChangeReasonKey] as! Int

 // get keys changed.

        let changeKeys = notification.userInfo![NSUbiquitousKeyValueStoreChangedKeysKey] as! [String]     

   switch changeReason {
    case NSUbiquitousKeyValueStoreInitialSyncChange, NSUbiquitousKeyValueStoreServerChange, NSUbiquitousKeyValueStoreAccountChange:
 // referesh and retrieve keys 
    case NSUbiquitousKeyValueStoreQuotaViolationChange:
 // Reduce Data Stored
    }

}

NB: All types of iCloud storage, for example, NSUbiquitousKeyValueStore offer only eventual consistency and thus does not support instant multiple device access.

Upvotes: 2

Related Questions