Glitch iOS Authentication Tutorial

This is a basic introduction to the Glitch iOS SDK, as well as an in-depth tutorial over OAuth in iOS.

The iOS SDK can be found here: https://github.com/tinyspeck/glitch-ios-sdk

Create an API Key

In order to use the SDK, you need an API key. Open up GlitchConfig.h in the Glitch iOS SDK folder. In there, you’ll see two #defines:

#define GCRedirectURI @""
#define GCAPIKey @""

It’s important that you create a new API key for each application you build. If you’re the impatient sort, for this sample app, there are some example values given in the comments in GlitchConfig.h. For this sample application, you could just uncomment the example values given and use those, but where’s the fun in that? Let’s go get a proper key of our own. Obtain a key here: http://developer.glitch.com/keys/new/

The App Name and Description can be anything you like, but do try to be reasonably descriptive when you fill those in. The Auth Redirect URI is the important part.
When we ask the SDK to authenticate the player, it opens up the Glitch authentication page in Mobile Safari. Once there, the player is prompted to sign in, if necessary, and then grant your app the permissions it needs. Once they’ve authorized your app on the Glitch site, the redirect URI is used to redirect the player back to your application. If we were writing a web app here, the redirect URI would be the URL of a page on our website that finished off the authentication process — something like http://www.myglitchywebsite.com/glitch/auth.php. On iOS, we don’t want the player sent back to a web site, we need to be returned to our app. The way we do this is to define a custom scheme— the scheme is the part of the URI that comes before the colon (so that would be http for a web application). In this example, I’ve used dopiazasampleapp for the scheme—you should use something that uniquely identifies your app.

Note: it’s very important that you choose a unique name for your custom schemes; if more than one app on an iOS device is registered for the same custom scheme, there are no guarantees as to which app will be launched to handle that scheme — the behavior is undefined. In other words, your app will probably break. The full URI I’ve used here is dopiazasampleapp://auth. You can put anything you like instead of auth, but auth is short, to the point and it’s what most people use, so we’ll just go with the flow.

Once you’ve submitted the form and got your key, copy it into the GlitchConfig.h file so it looks something like this:

#define GCRedirectURI @"dopiazasampleapp://auth”
#define GCAPIKey @“1234-0123456789abcdef0123456789abcdef0123456789”

Configure the URL Type
Open the sample project file here.

Now we’ve chosen our custom scheme, we need to make sure that iOS knows that our app can handle those URIs. Xcode refers to these as URL Types and they are defined in your app’s info.plist file. You can edit this file directly if you like, but Xcode 4 provides a much simpler interface for this. Select your project file, and the SimpleGlitchApp target, and choose the Info tab.

You’ll see the the URL Types section at the bottom of the main. In the Glitch Sample App, there will be an entry in there already — you can either edit that one, or delete it and add a new entry using the Add button in the bottom right hand corner. The identifier can be anything you like, although it’s usual to use the standard reverse-domain-name form here, and typically it would match your bundle identifier. The URL scheme you enter should exactly match the scheme that you created for your redirect URI.

Launch the App
So, that’s everything set up. Click on the Run button to build and run the sample app in the iPhone simulator. When the app launches, the very first thing it will do is to launch Mobile Safari to take you to the Glitch web site to authenticate. Log in, if necessary, and then tap on the Allow button to grant the identity scope to your app. You will then be returned to your app and be greeted with a nice friendly welcome message.

Well that was pretty easy, wasn’t it? Let’s now take a closer look at the code in the Sample app and see just how all that is made to happen.

Create the Glitch Instance
The first thing we need to do is create an instance of the Glitch class. Typically, you would have a single Glitch instance that provided access to the API throughout the whole of your app. Our sample app is really very simple, with just a single view controller, so we’ll create the Glitch object as a property there. In a more complicated app, you’ll probably need to access the Glitch object from many different view controllers and so you might want to add it to your app delegate instead, or perhaps create a central singleton class that provides easy access to the Glitch object throughout your app.
If you look at the header file for the SampleViewController class, you’ll see the Glitch property declaration.

#import <UIKit/UIKit.h>
#import "Glitch.h"

@interface SampleViewController : UIViewController
<GCSessionDelegate, GCRequestDelegate> {
Glitch * _glitch;
UILabel * _playerNameLabel;
}

@property (nonatomic, retain) Glitch * glitch;

@end

The SampleViewController class also implements two delegate protocols: GCSessionDelegate and GCRequestDelegate — more on those in a moment. Now open up the SampleViewController.m file and look at the initWithCoder method. Here, we create the Glitch instance:

- (void)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        _glitch = [[Glitch alloc] initWithDelegate:self];
    }
    return self;
}

Now we have a Glitch instance, let’s take a look at how we actually authenticate with it.

Authentication
Before our app can do anything useful, it needs to make sure the player is authenticated.  In this simple example, we only have one view, so we’ll do this when the view is presented to the user. This takes just a single line of code:

-(void)viewDidAppear:(BOOL)animated
{
[_glitch authorizeWithScope:@"identity"];
}

Our sample app only needs to show the name of the player, so identity scope is sufficient for our needs. If we were expecting to use other API methods, then we might need to authenticate with additional permissions here.

But how do we know if the authorization process succeeds? Remember those protocols we specified in our SimpleViewController header? The GCSessionDelegate protocol is the one that is used to report back on how authentication has gone. There are three methods to implement:

- (void)glitchLoginSuccess;
- (void)glitchLoginFail:(NSError*)error;
- (void)glitchLoggedOut;

All three methods are marked as optional — you only need to implement the ones you need in your app.

There’s just one important step left. At the start of this example, we defined our custom scheme to use in the redirect URI. We still need to add the code that tells our app what to do when it is asked by iOS to handle the redirect URI. This all happens in the AppDelegate — when an app is asked to process a URL by iOS, the AppDelegate’s application:handleOpenURL: method is called. So, in SampleAppDelegate.m we add:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
[[_viewController glitch] handleOpenURL:url];

return YES;
}

Again, we just have a single line of code in this method — we call the handleOpenURL: method on our Glitch instance, passing through the URL we were given. That then takes care of completing the authentication process, and invokes glitchLoginSuccess or glitchLoginFail on the GCSessionDelegate, as appropriate.

Using the API
Now we’ve authenticated, and we know who our player is, we can finally start making calls to the API. Our sample application displays the username of the authenticated player and we get this information from the players.info API method. We can only call this method this once we’re sure that the authentication process was successful, so we’ll do that from our glitchLoginSuccess delegate method:

- (void)glitchLoginSuccess
{
GCRequest * request = [_glitch requestWithMethod:@"players.info" delegate:self];
[request connect];
}

As you can see, we create a GCRequest instance for the API method we want to invoke and then call the connect method to perform the actual API call. players.info doesn’t take any additional parameters, so we just use the requestWithMethod:delegate: method. If we were calling a method that required additional parameters, we would use requestWithMethod:delegate:params:. The delegate object must implement the GCRequestDelegate protocol, which we included in our SimpleViewController declaration earlier. There are two methods defined by GCRequestDelegate, both of them optional:

- (void)requestFinished:(GCRequest*)request withResult:(id)result;
- (void)requestFailed:(GCRequest*)request withError:(NSError*)error;

Finally, we add the requestFinished:withResult: method to our view controller class:

// Called when request was completed
- (void)requestFinished:(GCRequest*)request withResult:(id)result
{
    // Validate we've got the right response
    if ([request.method isEqualToString:@"players.info"])
    {
        // Perform validation on the response
        if ([result isKindOfClass:[NSDictionary class]])
        {
            // Get the status of the auth token
            id ok = [(NSDictionary*)result objectForKey:@"ok"];

            // Ensure that we're ok before proceeding! (the ok number is 1)
            if (ok && [ok isKindOfClass:[NSNumber class]] && [(NSNumber*)ok boolValue])
            {
                // Get the name of the player from the response
                id player_name = [(NSDictionary*)result objectForKey:@"player_name"];

                // Ensure we've got a valid player name
                if (player_name && [player_name isKindOfClass:[NSString class]])
                {
                    // Initialize the player name label if it isn't already initialized
                    if (!_playerNameLabel)
                    {
                        _playerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 200)];
                        // Set up additional label properties here if desired
                        [self.view addSubview:_playerNameLabel];
                    }

                    // Update the label text with our player name
                    _playerNameLabel.text = [NSString stringWithFormat:@"Hello, %@!",player_name];
                } // end of if (player_name && [player_name isKindOfClass:[NSString class]])
            } // end of if (ok && [ok isKindOfClass:[NSNumber class]] && [(NSNumber*)ok boolValue])
            else
            {
                // If we're NOT ok!
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Nooooo!" message:@"The API request was not ok!"
                                                               delegate:self cancelButtonTitle:@"Darn" otherButtonTitles:nil];
                [alert show];
                [alert release];
            }
        }
    }
}

Here, we check that the result matched what we were expecting — the request method should be players.info, and the result object should be an NSDictionary. The returned dictionary object contains the deserialized JSON data returned by the API method. If you want to see how those response objects are structured, you should take a look at the API Method Explorer. There, we can see that a typical JSON response to players.info  would look something like this:

{
"ok" : 1,
"user_name" : "David Wilkinson",
"player_name" : "dopiaza",
"player_tsid" : "PIF6IDNUOF01MFH",
"avatar_url" : "http:\/\/c2.glitch.bz\/avatars\/2011-08-27\/dae04cbe459971e70f8560ad28974a7b_1314458411_172.png"
}

The Glitch iOS SDK converts that JSON response into an NSDictionary containing the returned data using the popular SBJson library. You can read more about how the various JSON structures are mapped onto Foundation classes in the SBJson documentation here.

Finally, we set the text of the label to be the player_name value extracted from the API response. And there you have it — your first Glitch App.

Tips and Tricks
Using the SDK is really easy, but here are a few quick tips and tricks to help avoid some common pitfalls.

  • Always create a new API key and redirect URI for every app you create. Having multiple apps on your iOS device that share the same key and redirect URI may well cause odd things to happen.
  • When you receive an API result, always check the ok parameter. This will be set to 1 for a successful request, or 0 if there was a problem. If you find that it is 0, there will also be an error parameter returned, which will give you more information about what went wrong. Common errors are not_authenticated if the request wasn’t authenticated when it needed to be, invalid_token if the stored authentication credentials are no longer valid (perhaps the user has revoked them) and missing_scope means that the scope you are using doesn’t have sufficient privileges (for example, calling auctions.create with only read scope granted).
  • Remember, players can revoke permissions for your app at any time. If you want to find out if the authentication credentials you hold are still valid, use the auth.check method.
  • If you are unsure about what information will be returned by an API request, or how the response will be structured, use the API Method Explorer to see what will get returned.
  • Always authenticate with the lowest level of permission you can get away with. Don’t ask for write scope if your app only needs identity scope — you’ll just make people suspicious of what your app might be up to. If you find you need a more permissive scope later, you can always get the player to re-authenticate and grant additional permissions.

This entry was posted in Uncategorized, iOS, API and tagged Glitch, iOS, SDK, platform, API