Created
June 11, 2013 12:15
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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