One major thing I overlooked when releasing Hamster Chase is the fact that people don't want to upgrade to the full version because it will erase all their progress. This could have already cost me several hundred sales; but it's not too late to correct the issue!
iCloud allows different apps with the same key-value store identifier to sync data together. So, if both the free and full versions use iCloud, it would enable a user to pull their free-app level progress into their full-app without even pressing a button.
Furthermore, a user could install the same app on several devices, and keep the game progress synchronized between all of them! Pretty cool...
What about when the app already has local key values?
It's easy to release an iCloud-enabled app for the first time; but if you're like me, you already have values in the local keystore. So what do we do?
Option 1: "You don't need to do anything; if a value is absent from the cloud, just pull it from the local keystore."
Sure that's true, and eventually most or all the preferences will find their way into the cloud. The problem is that you have no control over how. Suppose someone installed your app on three devices; each with different "Best Time" values for various levels. Say they played for a few minutes on one, then for longer on the other, then even longer on the next. Each one introduced new keys to the cloud based on what levels they happened to play at the time. So the cloud basically gets a random mashup of "Best Time" values to distribute to the apps.
Option 2: "Write all the local keystore data to the cloud when you play for the first time since updating."
That's fine but there's a problem: The cloud will get all the "Best Time" values for the app the player decided to run first...and then that gets carried over to all their other apps. If the player downloaded the app to a new device and ran it for the first time...good bye profile.
Option 3: Let the player decide which device to pull default cloud values from.
That could work, although if they got really good "Best Times" on the device where they only advanced through half the game instead of beating it, they lose those times forever.
I went with:
Option 4: "Check whether the app installed on this device has ever synchronized with the cloud; and if so, make sure that the "best" value for each key gets written to the cloud.
In my implementation's "initial sync" with an installed app, I update one key at a time. If the cloud doesn't have the key, I write my local key-value to the cloud. If the cloud already has one, I write my local key-value to the cloud if and only if mine is "better." By better I mean I beat a level in less time; or I have more coins, or I'm further along in the game according to that value. If the cloud's value is better than my local one however, I will overwrite my local one with that of the cloud.
if the cloud is down, I'll try the initial sync again in the future. Eventually, all the apps will have my latest level progress and best times.
So far my idea seems to work, but I'm really going to have to test this thoroughly to be sure.