I am trying to store key-values with NSUbiquitousKeyValueStore. They seem to store fine while the app is installed, but if I delete the app off the device and run the app again, the key-values seem to be lost. Is this expected behaviour, or perhaps is there something I'm missing?
I am storing and retrieving values like so:
-(void)setString:(NSString*)stringValue forKey:(NSString*)keyValue {
NSUbiquitousKeyValueStore *iCloudStore = [NSUbiquitousKeyValueStore defaultStore];
[iCloudStore setString:stringValue forKey:keyValue];
[iCloudStore synchronize];
}
-(NSString*)getStringForKey:(NSString*)keyValue {
NSUbiquitousKeyValueStore *iCloudStore = [NSUbiquitousKeyValueStore defaultStore];
return [iCloudStore stringForKey:keyValue];
}
What I've already checked:
- I have enabled iCloud and key-value storage in Target Capabilities.
- iCloud Drive is enabled on my device and the app itself is enabled.
- I have waited for some time before trying to load the values to be sure it wasn't just a syncing problem.
I have registered an observer in the NSNotificationCentre as per Apple docs for NSUbiquitousKeyValueStoreDidChangeExternallyNotification. My observer is never called, on first run after install, or subsequent runs. My code(stripped back from Apple docs)
NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateKVStoreItems:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:store]; [store synchronize]; - (void)updateKVStoreItems:(NSNotification*)notification { NSLog(@"RECEIVED DATA"); }
Additional questions -
- Is there a way of telling when your data has synced to the cloud?(i.e. uploaded data)
- Or the reverse, is there a way of telling when your app has synced successfully from the cloud?(i.e. downloaded data) I would have hoped that NSUbiquitousKeyValueStoreDidChangeExternallyNotification would notify for this, but since I'm not receiving this notification, I suspect it's just for when another device has updated the data while the app is open, a suspicion that seems to be confirmed by Apple docs:
NSUbiquitousKeyValueStoreServerChange - A value changed in iCloud. This occurs when another device, running another instance of your app and attached to the same iCloud account, uploads a new value."
Did you enable iCloud in the Application Services for the app id in the Apple Developer Portal? After that you also have to create a provisioning profile for the app.
The only difference I see in my code is the "name:" parameter. You need to specify that you want to observe NSUbiquitousKeyValueStoreDidChangeExternallyNotification
Your code throws a warning in my environment
Instance method '-addObserver:selector:object:' not found (return type defaults to 'id')
I also have been using setObject:forKey: instead of setString:forKey: