Going Social – Using Google+ with iOS
Now that the Facebook SDK for iOS is in the bag here at House of Beor, the next social framework up is Google+ with iOS. I’m not really sure how popular G+ is, but I use it and generally find it pretty nice although I use it mostly for more technical stuff. Facebook is for family and G+ seems to be more for products, technology, programming stuff and things like this. I think there are also more possibilities around the circle concept for some of the projects I’m working on. In the end what I’m shooting for is an app that allows a user to pick from Google+, Facebook, or MS Live as an authentication and session management capability.
So onto Google+ SDK for IOS…but first in case you wanted to check out my Facebook SDK for iOS posts:
Configuring Google+ for iOS SDK
Step #1 – what’s ur google id? Lol – yes yes…I know it. So next steps is to look here: https://developers.google.com/+/mobile/ios/getting-started then you should have what you need to get going. I placed the extracted SDK folder in the same place as the Facebook iOS SDK – the Documents folder on my Mac. I left the option to copy the files over if necessary off. There’s some funny comments in the instructions about not needing to do this if you already have the files in your project, but I’m not sure what that means really. If I already had the files, why would I be doing this? Anyway…
The basic methods of the example from Google work fine by themselves, however there are a lot of cases that won’t get handled – for example what if the user logs out from G+ in another app and then comes back here – probably need some checks in applicationDidBecomeActive().
I also don’t like the embedding of code like this in the view rather than having this either in the app delegate or in a class designed to contain the logic centrally. There’s also the issue of the openURL call – this is the same call required for handling Facebook URL requests, but the return types are different so we’ll have to figure that out.
Initial Concepts for G+ and Facebook Together
My initial concept will be to have a session manager class as a property of my appDelegate. The session class will have a few basic things: service, sessionStartTime, currentToken, User. The key one is “service” (NSString) as this will be the current authentication service the app is using. User is s simple class that contains the obvious user crap. I’ll instantiate this in the appDelegate as a private property. In didFinishLaunchingWithOptions I can initalize the session and then do some checking to see if there are active tokens from a service already loaded:
// See if the app has a valid token for the current state. if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) { self.session.service = @"Facebook"; self.session.currentToken = FBSession.activeSession.accessTokenData.accessToken; } else if ([[GPPSignIn sharedInstance] authentication]) { self.session.service = @"GooglePlus"; self.session.currentToken = [[GPPSignIn sharedInstance] authentication].accessToken; } else { // No, display the login page. [self showLoginView]; }
Here I’ll check thru each type of possible token types and see what’s there. I can also use this opportunity to stash the current token and other session data. If there is no token then I pop up the login view controller.
The login view controller is very simple. A button for each service. Click the button and call a function for each service. Figure out which button and pass the ball back to the app delegate:
- (IBAction) performLogin:(id)sender { [self.spinner startAnimating]; AppDelegate* appDelegate = [UIApplication sharedApplication].delegate; if (sender == self.faceBookSignInButton) { [appDelegate openSession:@"Facebook"]; } else if (sender == self.googlePlusSignInButton) { [appDelegate openSession:@"GooglePlus"]; } else if (sender == self.msLiveSignInButton) { [appDelegate openSession:@"MsLive"]; } }
In the appDelegate is the openSession function:
- (void)openSession: (NSString*) service { self.session.service = service; if ([self.session.service isEqualToString:@"Facebook"]) { [FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler: ^(FBSession *session, FBSessionState state, NSError *error) { [self sessionStateChanged:session state:state error:error]; }]; NSString * token = FBSession.activeSession.accessTokenData.accessToken; NSLog(@"My Facebook token is: %@", token); } else if ([self.session.service isEqualToString:@"GooglePlus"]) { GPPSignIn *signIn = [GPPSignIn sharedInstance]; signIn.clientID = kClientId; signIn.scopes = [NSArray arrayWithObjects: kGTLAuthScopePlusLogin, nil]; signIn.delegate = self; [signIn authenticate]; //passes control to finishedWithAuth } }
You’ll still need to have the functions to handle the final disposition of the process – finishedWithAuth for G+ and sessionStateChanged for FaceBook. Both are documented in their basic samples. The last thing I did was add a “closeSession” method in the app delegate that I Can call from any viewController. What this one does is pick up the current service type to “”.
- (void) closeSession { if ([self.session.service isEqualToString:@"Facebook"]) { [FBSession.activeSession closeAndClearTokenInformation]; } else if ([self.session.service isEqualToString:@"GooglePlus"]) { [[GPPSignIn sharedInstance] signOut]; self.session.service = @""; [self showLoginView]; } }
That seems to work pretty well – but I think now that at least I have the basics working I will start all over again with a better architecture. I want all the logic for the login/logout ans sessions in a singleton manager class that is shared across the app, This would get most of the logic out of the app delegate and also make it easier to pass messages.