As I Learn CloudKit Syncing - Part 0
We released Qiktionary a little over a month ago. It’s a playful word game that allows players to unlock interesting facts by solving a mastermindish word puzzle. There are two modes: single player (the main game) and multiplayer where you can challenge your friends on Game Center to a round of three games. Qiktionary works on both iPhone and iPad.
Since it works on both the iPhone and the iPad, we considered the possibility of adding syncing. We knew some people would play on both their iPhone and iPad and would want their games to sync to all their devices. Multiplayer is built on top of Game Center matchmaking so we already have syncing there taken care of; but single player data is all just stored locally in a sqlite database.
I punted on syncing until a week ago when I started implementing Game Center leaderboards and achievements for the single player game. Without syncing, the following scenario is likely to happen to people that play on both an iPhone and an iPad on the same Game Center account:
- Play many games on their iPhone, earning achievements that unlock prizes and rocket them up the leaderboard. The sqlite database on their iPhone diligently holds the records for all these games played. Game Center stores the info about their leaderboard scores and achievements
- Put down their iPhone and pick up their iPad, which doesn’t know anything about all those games hidden away on their iPhone
- Qiktionary on the iPad shows them all these achievements they’ve earned even though locally they haven’t played a single game.
- Play a game on their iPad. Qiktionary updates their score on the leaderboard based on that single game. Player rockets back down the leaderboard. Qiktionary also attempted to award them the “played your first game” achievement even though they’ve already played many games on their iPhone.
- Player is sad.
- Player leaves bad review on App Store.
- Qiktionary is sad.
So it seems to me that there is no way of getting around implementing syncing when doing Game Center leaderboards/achievements for a univeral iOS game.
Which brings me to CloudKit.
I don’t have a lot of time to build in syncing. I’m not going to be running my own servers. There isn’t a ton of data to sync (if a player completely finishes Qiktionary they will have only generated at most 10MB). Qiktionary for now is iOS only and even if we do expand to other platforms I’m okay with the new CloudKit REST and JS APIs being sufficient to support that move. CloudKit also has nice support for this type of syncing strategy (which they call tiny data, all devices).
So: CloudKit. This is what I’m using and I’ve been learning all I can about it the last couple of days. I’ve watched all the WWDC sessions (some multiple times). Introducing CloudKit and Advanced CloudKit from last year and CloudKit Tips and Tricks from this year were especially helpful. The Advanced NSOperations talk from this year has also given me a strategy for working with CloudKit operations that I think I am happy with (I’ll cover this in a future post). There isn’t a ton of Sample Code but I’ve learned some from the CloudKit Catalog and the live JS version is pretty helpful for quickly getting a feel for the APIs. I’ve also learned a lot by looking at the source for the newly released CKSIncrementalStore.
There are a decent amount of CloudKit tutorials out there but I’ve found most of them are focused on the Big Data, Tiny Phone strategy of CloudKit. This is the strategy used by things like iCloud Photos.
Which is why I am writing this series (shamefully copying David Smith’s As I Learn watchOS series). I’ve just started implementing sync but I am going to try and talk through some of the problems I run into and figure out which things work and which things don’t.
Stay tuned for Part 1 where I will be talking through the “Tiny Data, All Devices” strategy of CloudKit.