iOS Walkthrough - adam-roth/matchbook GitHub Wiki

Overview

This page provides a high-level walkthrough covering the basic details of the matchbook iOS SDK and example application. Use it to become familiar with the core API and some of its capabilities.

Getting Started

The simplest way to get started is to grab the iOS example application, located under '/Examples/Objective-C/MatchmakingExample'. This project includes everything you need to familiarize yourself with the Matchbook iOS SDK, including a prebuilt version of the SDK framework and a simple "game" that demonstrates the basics.

Basic Setup - Server URL

The Matchbook SDK requires two pieces of configuration information from you. The first is the URL of the API server to use (if you do not provide one, the SDK will default to 'http://localhost:8080/ap/'). So you'll need to find or set up a running Matchbook server instance.

Once you have that, there are a couple of different ways to tell the Matchbook SDK what server to use. The first is to simply put the URL into your application's 'Info.plist' file, under the 'au.com.suncoastpc.matchbook.server' key. This should be a String value, which contains the full server URL and context-path (so a leading 'http(s)://', and a trailing '/ap/' should be included).

The second method is to simply pass the desired server URL as a parameter when you create your 'SCMatchmaker' instance. More on that later.

Basic Setup - API Key

The other piece of information required by the Matchbook SDK is the private/API key to use for your application. You can get this by registering your application id/bundle-identifier on the Matchbook server that you plan on using. You should register your app's bundle-id exactly as it appears in Xcode/iTunes Connect/etc.. When you do so the Matchbook server will give you an API key, which you can pass to the 'SCMatchmaker' when you instantiate it.

Joining a Match

Once you have those things, creating/joining a match is as simple as setting up a fresh 'SCMatchmaker' instance and asking it to join the next available match:

- (void) setupMatch {
    matchmaker = [[SCMatchmaker alloc] initWithKey:MATCHMAKER_KEY andDelegate:self];    //XXX:  uses server URL contained in Info plist
    //matchmaker = [[SCMatchmaker alloc] initWithKey:MATCHMAKER_KEY andServerAddress:@"http://127.0.0.1:8080/ap/" andDelegate:self];    //XXX:  explicit server URL
    match = [[matchmaker autoJoinMatchWithMaxPlayers:NUM_PLAYERS creatingIfNecessary:YES] retain];
    
    if (match) {
        //congrats, you've got a match!
    }
    else {
        //oops, couldn't join the match; probably your server is down or you used the wrong API key, check the log for details
    }
}

Note that this example shows both methods for specifying the server URL. The first call will use the URL contained in your app's 'Info.plist'. The second will use the server URL that is passed into the constructor.

Handling Match Events

Also note that the 'SCMatchmaker' expects to receive an object that conforms to the 'SCMatchmakerDelegate' protocol. This protocol includes the following methods:

- (BOOL)shouldAcceptJoinFromPlayerWithId:(NSString*)playerId andDetails:(NSDictionary*)playerData;
- (void)receivedData: (NSDictionary*)data fromPlayerWithId:(NSString*)playerId;
- (void)playerJoinedWithId:(NSString*)playerId andDetails:(NSDictionary*)playerData;
- (void)playerLeft:(NSString*)playerId;
- (NSDictionary*) localPlayerDetails;

The most important of these delegate methods is 'receivedData:fromPlayerWithId:'. This method is invoked whenever a packet is received from another player in the match. When this happens, you'll most likely want to inspect the contents of the packet, take some actions, and possibly respond by sending a fresh packet from the local device. For instance:

//handles the various messages that we can recieve from our "game"
- (void)receivedData: (NSDictionary*)data fromPlayerWithId:(NSString*)playerId {
    //handling messages from players
    if ([[data objectForKey:@"message"] isEqual:@"PING!"]) {
        //ooh look, somebody pinged us
        [self performSelectorOnMainThread:@selector(respondToPing) withObject:nil waitUntilDone:YES];
    }
    else if ([[data objectForKey:@"message"] isEqual:@"increment"]) {
        //increment our shared game counter and update the UI
        @synchronized(countLabel) {
            counter++;
            [self performSelectorOnMainThread:@selector(updateCounter) withObject:nil waitUntilDone:YES];
        }
    }
    else {
        //the player's background color must have updated (only other message that we expect)
        NSMutableDictionary* params = [NSMutableDictionary dictionary];
        [params setObject:[data objectForKey:@"color"] forKey:@"color"];
        [params setObject:playerId forKey:@"player"];
        [self performSelectorOnMainThread:@selector(updateLabel:) withObject:params waitUntilDone:NO];
    }
}

Obviously that's a fairly contrived example, but you get the idea. What goes into the packets that get sent around and how your app responds to them is entirely up to you.

Sending Data

The packets themselves are sent between players by way of the 'SCMatch' instance that the 'SCMatchmaker' returned when you called 'autoJoinMatchWithMaxPlayers:creatingIfNecessary'. The main API methods of interest here are:

- (void) broadcastMessage:(NSDictionary*)message;
- (void) sendMessage:(NSDictionary*)message toPlayer:(NSString*)playerId;

The difference between these two methods should be fairly self-explanatory. The former broadcasts a message to all players in the game. The latter sends a message directly to a specific player, and does not notify anyone else who is in the match.

Further Reference

That covers the basics, though to get a better feel for the complete Matchbook SDK you should read through the other methods contained in the example project's 'ViewController.m' class. And also through the SDK code/headers as well.