Google sign-in with 1Password

I'm heavy user of 1Password. This is great tool, with all my password. Since iOS 8.0, 1Password gave me extension so now I can login to applications with 1Password, without typing my login details (I use really long login). This is great solution and I would recomend it to any developer.

Developers, please add support for 1Password in your application!

Just check this video https://vimeo.com/102142106

Problem: Google sign-in without 1Password

Many applications have integrated Google authentication, so I can sign-up with my google account to the service. I found that Google sign-in view never offered me 1Password integration, and since I'm beta tester of one of such app, It bugs me.

So I wondered... how It can be archived? turn out it can be done. I write this guide, for anyone who integrate Google sign-in with the app, so you have it ready to use.

Typical sign-in screen:

Setup

I assume you already know that you should not use Google+ iOS SDK. Why? because with this SDK sign-in is done with external browser (Safari, Chrome), and you probably want to have in-app experience. Use Google Toolbox for Mac - OAuth 2 Controllers.

Ingredients
1. Google Toolbox for Mac - OAuth 2 Controllers
2. 1Password Extension for iOS Apps

I use Cocoapods, and my Podfile is like this:

pod 'gtm-oauth2', '~> 1.0'
pod '1PasswordExtension', '~> 1.1'

Caution: To sign in to Google services with OAuth controllers, first obtain a client ID and secret from the API Console.

Sign-in View controller

Here you can find GTMOAuth2ViewControllerTouch that is build with integrated UIWebView, and can handle complete OAuth2 flow.

#import <GTMOAuth2ViewControllerTouch.h>

GTMOAuth2ViewControllerTouch *googleAuthViewController = [[GTMOAuth2ViewControllerTouch alloc]
                       initWithScope:@"https://www.googleapis.com/auth/userinfo#email"
                       clientID:kClientId
                       clientSecret:kSecretId
                       keychainItemName:@"GooglePlus_Sample_App"
                       delegate:self
                       finishedSelector:@selector(viewController:finishedWithAuth:error:)];

present view controller to the user

[self.navigationController pushViewController:googleAuthViewController animated:YES];
Web View

"Steal" WebView. It's not hidden so you can get it and keep reference around

@property (weak) UIWebView *webView;

Because GTMOAuth2ViewControllerTouch is backed by XIB, view have to be loaded manually (this is why I call .view property)

googleAuthViewController.view; // trick
self.webView = googleAuthViewController.webView;
Action button

add 1Password button to the view

// add 1Password button
UIButton *onePasswordButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[onePasswordButton addTarget:self action:@selector(onePasswordAction:) forControlEvents:UIControlEventTouchUpInside];
[onePasswordButton setFrame:CGRectMake(0, 64, 150, 44)];
[onePasswordButton setTitle:@"1Password" forState:UIControlStateNormal];
[onePasswordButton setImage:[UIImage imageNamed:@"onepassword-button"] forState:UIControlStateNormal];
[googleAuthViewController.view addSubview:onePasswordButton];

For better user experience you should check if 1Password extension is available first, and present button on;y if action is possible to perform.

[[OnePasswordExtension sharedExtension] isAppExtensionAvailable]

effect

Integrate 1Password extension

finally add 1Password action for the button

#import <OnePasswordExtension.h>

- (IBAction) onePasswordAction:(UIButton *)sender
{
    [[OnePasswordExtension sharedExtension] fillLoginIntoWebView:self.webView forViewController:self sender:sender completion:^(BOOL success, NSError *error) {
        if (!success) {
            NSLog(@"Failed to fill login in webview: <%@>", error);
        }
    }];
}
Effect

You just addedd 1Password integration. A lot of users is happy, thank you.

Sample project

Here you find Github repository with presented code: https://github.com/krzyzanowskim/Google1Password

PS. Do you need samples for Swift ?