oAuth for iOS applications

    Trelejaz Club Welcome Screen for iPhone
    It's getting dark. Warm August Saturday predisposed to implement oAuth authorization on Google and Facebook for the iOS client of the club of intellectual games.

    A superficial search on the network hinted to us that both companies provide tools for developers to quickly automate this routine and return to more interesting tasks of directly programming the game process.

    Quick links to the libraries themselves: Google - gtm-oauth2 , Facebook - facebook-ios-sdk

    On the nuances of integration under the cat.


    Google


    First of all, go to the API Console and get the Client ID and Client Secret there. The procedure is fast and free.

    We connect the gtm-oauth2 library to the project. On the authorization button via google we hang something like:

    #import "GTMOAuth2ViewControllerTouch.h"
    ...
    - (void)onGoogleAuth:(id)sender 
    {
        GTMOAuth2ViewControllerTouch *viewController;
        viewController = [[[GTMOAuth2ViewControllerTouch alloc] 
                           initWithScope:@"https://www.googleapis.com/auth/userinfo#email"
                           clientID:@OAUTH_GOOGLE_CLIENT_ID
                           clientSecret:@OAUTH_GOOGLE_CLIENT_SECRET
                           keychainItemName:@"OAuth2 MYAPP: Google"
                           delegate:self
                           finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease
                          ];
        [[self navigationController] pushViewController:viewController animated:YES]; 
    }
    

    This opens the ViewController with a browser and a standard web authentication request from Google. After the user goes through the process of entering the email and password, the following function is called, where you can already take the confirmed email of the logged-in user and respond to the fact of a successful login:

    - (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
          finishedWithAuth:(GTMOAuth2Authentication *)auth
                     error:(NSError *)error {
        if (error != nil) {
            // Authentication failed
        } else {
            if (auth.canAuthorize){
                // auth.userEmail 
            }
        }
    }
    

    This was enough for our task, but the Google API is not limited to this, and through different scope you can request rights to work with many Google services. Including youtube and buzz.

    Facebook


    Facebook is a little more complicated. First, as usual, you need to register your "application" here , unless, of course, you have not done this before.

    Next, install facebook-ios-sdk into the project, add the implementation of the FBSessionDelegate and FBRequestDelegate protocols to the delegate of your application class

    #import "FBConnect.h"
    @interface AppDelegate : NSObject  {
    	UIWindow *window;
            ....
            Facebook* facebook;
    }
    ....
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
    - (void)fbDidLogin;
    - (void)request:(FBRequest *)request didLoad:(id)result;
    
    The simplest implementation looks something like this:
    - (void)facebookLogin
    {
        if (!facebook) facebook = [[Facebook alloc] initWithAppId:@FACEBOOK_APP_ID];
        [facebook authorize:nil delegate:self];
    }
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url 
    {
        return [facebook handleOpenURL:url]; 
    }
    - (void)fbDidLogin {
        [facebook requestWithGraphPath:@"me" andDelegate:self];
    }
    - (void)request:(FBRequest *)request didLoad:(id)result {
        // result - NSDictionary
    };
    


    Visually, it looks like a way out of the application, opening a separate Safari process, a web login and confirmation form from Facebook, closing the browser and reopening the application with an already logged-in user. Indeed, the browser runs as a separate process from the application. But how does the application intercept return from the browser? The casket opens relatively simply. In the info.plist of your application, we register the type of URL that intercepts your application, after which Safari becomes “in the know” where to transfer control. We do this from Xcode as follows (instead of YOUAPPID we write the ID of our application on Facebook):

    Editing info.plist to handle external URLs


    Voila, it remains in the request didLoad function to make a reaction to the user's Facebook input, and the point is in the hat.

    Requesting Facebook rights, storing session keys in KeyChains, and other goodies are detailed in the documentation. For our purposes (simple authentication), the above was enough, but the capabilities of the API there are quite wide. Up to "post a photo on the wall" and "send a message to a friend by xmpp in a pin".

    Friday the 13th


    No, we are not talking about a maniac in a hockey mask and with a huge cleaver. It will be a small fly in the ointment, which is expressed in the fact that for some reason everyone considers it their duty to put one more JSON implementation in their “library” of two classes. Citizens, when will it stop? Moreover, both Google and Facebook use the same implementation. Namely SBJSON, moreover, of different versions and incompatible on interfaces. A simple file, of course, solves the problem, but, I'm afraid, due to the lack of a regular implementation from Apple, iOS developers need to come up with a new term, Json-Hell.

    Keep the JSON implementation (as well as zlib, and other stuff) in the project in a single copy, and may the force be with you.

    Also popular now: