Skip to content

Instantly share code, notes, and snippets.

@ianbarber
Created June 11, 2013 12:15
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ianbarber/5756364 to your computer and use it in GitHub Desktop.
Save ianbarber/5756364 to your computer and use it in GitHub Desktop.
A simple implementation of Google+ Sign-In on iOS using version 1.3.0 of the SDK: http://developers.google.com/+/mobile/ios
//
// AppDelegate.m
#import "AppDelegate.h"
#import "GoogleOpenSource/GTMOAuth2Authentication.h"
#import "MainViewController.h"
#import "SignInViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Before configuring, make sure to have:
// 1. Created a custom URL matching your bundle ID.
// 2. Added the GooglePlus.framework, GoogleOpenSource.framework
// and GooglePlus.bundle to your project.
// 3. Added the SystemConfiguration and Security frameworks.
// 4. Make sure you have -ObjC in your Other Linker Flags setting. Otherwise,
// what is likely to happen is that the sign in button wont be able to find
// the categories it needs, and you'll get odd errors like:
// "[__NSDictionaryM gtm_httpArgumentsString]: unrecognized selector".
// The casing is important!
// Configure the client ID from the API console:
// http://developers.google.com/console
[[GPPSignIn sharedInstance] setClientID:@"YOUR_CLIENT_ID"];
// Configure callbacks from the sign-in process to be sent to this object.
// Note that we added the GPPSignInDelegate protocol to the AppDelegate.h.
// If we don't set this, then the process will complete, but we'll never get a
// call to our |finishedWithAuth:error:| method!
[[GPPSignIn sharedInstance] setDelegate:self];
// If we needed to request access to write app activities, we could also set
// the |actions| property. If we wanted to add any scopes, we would add to the
// scopes property. In the absence of more specific requirements, the default
// if for the Google+ login scope.
// Now we can try and sign-in right away. We could store the return type in a
// property in case the library requires making a network call and the
// callback is delayed - this allows controllers to check whether a callback
// can be expected.
if (![[GPPSignIn sharedInstance] trySilentAuthentication]) {
// If we aren't silently signing-in, we'll might show a sign-in button
// If we are, we'll defer the decision till the |finishedWithAuth:error:|
// call so we don't have a flash of the sign-in button.
self.viewController = [[SignInViewController alloc] init];
} else {
// Create the view controller that the user will interact with. We don't
// need to pass anything over here, as it can check the state of play using
// the |GPPSignIn sharedInstance|.
self.viewController = [[MainViewController alloc] init];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error) {
// If the error value is set, something has gone wrong. There are several
// possible values, but all indicate the user is not signed-in, and the auth
// should not be used.
NSLog(@"Sign-In Error: %@", error);
if ([error code] == -1) {
NSLog(@"Unknown error, but user probably cancelled.");
} else if([error code] == 400 &&
[[error domain] isEqualToString:@"com.google.HTTPStatus"]) {
NSLog(@"400 error, user has probably disconnected using the "
"app managment page.");
}
// Ensure we have a clear setup for next sign in.
[[GPPSignIn sharedInstance] signOut];
} else {
// We're signed in! We wont do much here, as the controllers can test
// the sign-in state via the |sharedInstance| on |GPPSignIn|, but for more
// complex applications writing an notification might be a good way of
// signalling the state change.
}
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// We need to use the helper GPPURLHandler class to manage the open URL. This
// is used for the response from the Google+ application or the browser after
// a user has been taken away to authorise an application. It also handles
// callbacks after sharing, and if the application is opened with a deeplink!
//
// If you need to combine this with other URL handlers, you can just test the
// returned BOOL, and hand over to the next handler in the chain if the return
// is NO.
return [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
@end
//
// ViewController.m
#import "GooglePlus/GooglePlus.h"
#import "SignInViewController.h"
@implementation SignInViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Create the Google+ Sign-In button. It automatically refers to the
// |GPPSignIn sharedInstance| so we don't need to wire it up.
GPPSignInButton *button = [[GPPSignInButton alloc] init];
// We can configure various properties, in this case, choosing the wide
// version of the button. The image and translated text are loaded from the
// GooglePlus.bundle - if you forget that, the button will be there, but
// invisible!
[button setStyle:kGPPSignInButtonStyleWide];
[self.view addSubview:button];
// This is just the autolayout code to center our button.
button.translatesAutoresizingMaskIntoConstraints = NO;
// Center the button vertically.
NSLayoutConstraint *constraint = [NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0f
constant:0.0f];
[self.view addConstraint:constraint];
// Center the button horizontally.
constraint = [NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f];
[self.view addConstraint:constraint];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment