TicTacToe: Multi-device syncing with Simperium!

Simperium is a cross platform framework that allows you to seamlessly sync data through multiple devices.

Tic Tac Toe is one of the simplest games you can possibly think of: two players take turns to place a piece (either a cross or a circle) on a 3×3 matrix. The first player that succeeds in placing three marks in either a horizontal, vertical, diagonal or antidiagonal wins the game.

We have built a single-device Tic Tac Toe game for iOS: source code available here. In this tutorial we’ll be learning how to integrate the Simperium framework, and how to enable multi-device data synchronization without writing a single line of backend code.

Our approach to implement the data model will be straight forward. We will maintain two collections:

Players:

Each player will have a unique ID, and will make sure that as long as the app is active, its uniqueID will be present in the Players collection. We will rely on this mechanism to initiate a match between two players.

Match:

The match object itself will have three attributes: the ID of both players, an array representing the status of the gameboard, and an extra flag we’ll use to indicate which player should perform the next move.

Let’s dive into the details!

1. Integrating the Simperium Framework

First of all, we’ll need to add drag the Simperium.xcproj file to our TicTacToe project, as seen below:

Drag Simperium Project

Once ready, let’s make sure we’re linking the required frameworks:

Required Frameworks

Since Simperium is an Objective C framework, we will need to instruct Xcode’s linker to work with Objective C libraries as well. In order to do so, let’s add the ‘-ObjC‘ string in the Other Linker Flags, under the project’s Build Settings, as seen here:

LinkerFlags

At last, we’ll need to add Simperium as a target dependency, in the Build Phases section of our project:

2. Updating our Data Model

Simperium is designed to listen to your CoreData Context, and efficiently sync delta’s through the network.

As a requirement, the classes you want to sync must subclass SPManagedObject -instead of NSManagedObject-.

We’ll need to also store two extra attributes per object, used internally by Simperium: simperiumKey and ghostData, both of NSString kind.

Let’s open our Data Model, and update both, Match and Player entities, accordingly:

1. MatchSchema

2. PlayerSchema

3. Adding a New Simperium App

We’ll need to signup for an account at Simperium’s website. Once there, let’s add a brand new app. We’ll need both, the AppId and AppKey, to initialize our instance of Simperium:

NewApp

There are several ways in which you can implement user authentication: the framework itself already provides a customizable User Interface to perform Signup and Sign-In.

However, in this particular project, we want to offer a signup-free experience: we want our users to be able to begin playing Tic Tac Toe, as soon as the app finishes launching.

In order to do so, let’s pre-generate a user token: every instance of this game will share the same user. You can find the Generate Token button in the Browse Data section of your app:

GenerateToken

4. Updating our CoreData stack

One of the benefits of using Simperium’s library is that Core Data disk operations are performed in a background thread, automatically, by the library. As a requirement for this to work, the Main ManagedObjectContext must not have its persistentStoreCoordinator set.

In our TicTacToe game, we’ve wrapped up all the CoreData initialization code in a single class, called TTCoreDataManager (Header | Implementation). The only difference with a regular CoreData stack initialization can be seen below:

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

// persistentStoreCoordinator must be nil on the main context!:
// [_managedObjectContext setPersistentStoreCoordinator:coordinator];

5. Starting Simperium

We’ll be initializing and authenticating our Simperium instance in the AppDelegate itself, as soon as the application:didFinishLaunchingWithOptions: method is executed:

- (void)startSimperium
{
	TTCoreDataManager* manager = [TTCoreDataManager sharedInstance];

	self.simperium = [[Simperium alloc] initWithModel:manager.managedObjectModel
											  context:manager.managedObjectContext
										  coordinator:manager.persistentStoreCoordinator];
}

- (void)authenticateSimperiumIfNeeded
{
	if (self.simperium.user.authenticated) {
		return;
	}
	
	[self.simperium authenticateWithAppID:TTSimperiumAppId token:TTSimperiumToken];
}

After calling the two routines outlined above, we’ll have a Simperium instance initialized with manual authentication, and our CoreData stack will be ready to begin operating.

We must also call the method authenticateSimperiumIfNeeded everytime the app becomes active, and signout from Simperium’s backend when the app becomes inactive.

We’ll rely on the following lines of code to do so:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
	[self authenticateSimperiumIfNeeded];
}

- (void)applicationWillResignActive:(UIApplication *)application
{
	[self.simperium signOutAndRemoveLocalData:YES completion:nil];
}


6. Next Up…

At this point we have a fully functioning TicTacToe game, we have successfully integrated the Simperium Framework, and we’re automatically authenticating the user when the app is brought to foreground (and logging off when the app is closed).

In the second part of this tutorial, we’ll learn how to signal our presence, initiate matches between two players, and how to sync our board… everything, just with Simperium Sync.

Stay tuned…!

Learn more about how to integrate Simperium into your iOS app.

2 thoughts on “TicTacToe: Multi-device syncing with Simperium!

  1. TicTacToe: Multi-device Syncing part #2 – Simperium Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s