8

My app uses iCloud (key-value store) to sync an unique id between multiple devices. This works accept at the point were it really has to work, at the first launch of the app. It looks like the device isn't yet familiar with the values from iCloud at first launch, only after the app is installed and has been running for a while.

I check for the iCloud value in the viewDidLoad function on main view of the app.

So, my questions:

  • Is this the expected behavior?
  • If yes, is there another solution?
  • Could it be the case this is only a problem when running from Xcode, not the shipping version? If so, how to test?

Thanks!

Jasper

Jasper Bel
  • 83
  • 1
  • 3
  • See this question: http://stackoverflow.com/questions/12539266/icloud-nsubiquitouskeyvaluestore-initial-sync-access-delay-how-to-handle – erkanyildiz Dec 28 '12 at 11:41

3 Answers3

8

I had a similar issue where the NSUbiquitousKeyValueStoreDidChangeExternallyNotification wasn't triggering on the first launch after install, no matter how long I waited. Setting an initial key in the NSUBiquitousKeyValueStore seemed to solve this.

Immediately after adding the observer to the default store, I call:

[[NSUbiquitousKeyValueStore defaultStore] setString:@"testValue" forKey:@"testKey"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];

I use different keys (i.e. not testKey) for the actual data I want to sync.

Jellyjoey
  • 188
  • 2
  • 6
  • 1
    I've implemented this and it seems to work well. Bottom line, I don't rely on any of the data I get back from iCloud until my observer function is first called. Once it has been called, I see all the values that I saved in previous instances of the app. I test this by deleting the app, rebooting the phone, and waiting about 10 minutes. Not sure if all those steps are required, but it seems to make iOS return nil for the data initially, and then it comes through correctly after the observer function is called a few seconds later. – Nicholas Jan 08 '13 at 17:17
  • didn't help. It just appears iCloud servers response can be extremely slow accessing save or load, and your app needs to be able to handle these async events. data is usually available.... "later", but rarely within 30 seconds of app start. – CthulhuJon Jan 22 '14 at 23:30
2

When you first run an iCloud enabled App it has to pull all the data from Apple servers. The time it takes to do so depends on many things like what kind of network you're currently on (Edge, 3G, GPRS, WLAN). It also depends on how much traffic the iCloud server currently has to handle so the request to the iCloud server may take a few more seconds, no matter what type of network connectivity you have.

To sum it up: Yes, it sounds absolutely normal.

If running your App depends on those settings consider implementing a "Wait" or "Loading" view that stays on the screen as long as it takes for the App to perform a initial synch and load all needed data from the cloud. To not block the UI forever also implement a timeout for this view (if iCloud data not loaded within X seconds, dismiss the view and notify user).

Björn Kaiser
  • 9,882
  • 4
  • 37
  • 57
  • Thanks for your response! Is there a way of checking if the initial iCloud sync finished? – Jasper Bel Jul 16 '12 at 18:21
  • You have to subscribe to the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification. Theres an example in the documentation :-) http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/UserDefaults/StoringPreferenceDatainiCloud/StoringPreferenceDatainiCloud.html – Björn Kaiser Jul 16 '12 at 19:01
  • @BjörnKaiser I have the same problem but no matter how long I wait on the first app launch, no notification ever comes, and this is when I know that the data is present on the keyValueStore in iCloud. – pulkitsinghal Sep 28 '12 at 13:07
  • 1
    Filed with apple @ bugreport.apple.com, 12394404 - NSUbiquitousKeyValueStore notifications do not fire on first app launch – pulkitsinghal Sep 28 '12 at 13:19
  • I have the same problem... sometimes is 50% reliable, for other users 100% fail. – CthulhuJon Jan 22 '14 at 01:56
1

You have no guarantee NSUbiquitousKeyValueStore would have finished its first synchronization as your app is launched for the first time. (In fact, on iOS 5, it's often starting to sync as you launch your app for the first time).

There is no way to know if the first initial sync has already happened, is ongoing or has finished. You can (in fact should) subscribe to NSUbiquitousKeyValueStoreDidChangeExternallyNotification. The trick is that if your store is empty on the iCloud server, you won't get any notification after the initial sync (since your local store is empty and the cloud store is empty as well, nothing really changed "externally" after the initial sync…)

Normally, you should not rely on the initial sync being done.

Be optimist at launch, even if your store is empty, push your values (e.g. your unique id) right away. If the initial sync happens concurrently or after and there is already some value on the server, your local values will be reset to the server values and you will get the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification with the NSUbiquitousKeyValueStoreInitialSyncChange reason.

Finally, if you really think knowing about the initial sync being completed or not, please file a bug to bugreport.apple.com and explain why you really need that.

Julien
  • 3,427
  • 20
  • 22