So as we talked about in our last video,
the new Google Sign-In Library contains
a number of improvements over what we had before.
It's smaller, it's a better user experience,
and it accepts all Google accounts even if they're not
Google+ accounts.
But how exactly do you add it to an iOS project?
Well, let's find out in this exciting episode of "Route 85."
[MUSIC PLAYING]
So I have a fresh new Xcode app that I
want to add the new Google Sign-In Library to.
For the purpose of this video, I'm
going to do everything in Swift 1.2,
but it's very similar in Objective-C,
just add a few more brackets here and there.
Now, the first thing I'm going to go through
is going through all of the configuration and setup steps,
always the most fun part of any project.
That was sarcasm.
Actually, it's not too bad now with the new configuration flow
that we have.
So the first thing I'll do is go to developers.googl
e.com/mobile/add.
Now I'll need to enter my project name
and my bundle ID here.
And on this next page, I'm going to select Sign-In and click
the Enable button.
It's going to go ahead and create an OAuth client
ID for me behind the scenes, which is very helpful.
And I don't need to do anything else right now,
so I'm just going to click Continue.
And then on this last page, I have a plist file
that I am going to download.
I also have this important line of text
that I'm going to need for my podspec file,
so let's copy that.
OK, up next, I'm going to configure my CocoaPod
to install the Google Sign-In Library.
I'll assume you know a little something about CocoaPods,
but if not, why not check out this video?
So I'll do a little pod init here, edit the file,
and paste in that line I copied earlier
from our Configuration Tool.
You'll notice this is the Google/signin CocoaPod, which
not only includes Google Sign-In, but also a few helper
libraries that will help me with the configuration process.
So I'm going to type pod install,
and CocoaPods will download the Google Sign-In Library for me.
And once that's done, I'll open up my .xcworkspace to see
my new project.
Oh, hello, pod library.
Glad you could join us!
Now remember that plist file I downloaded earlier?
I'm just going to add it to my Xcode project like so.
OK, now, next step, we need to add two URL schemes
to our project.
These basically allow other Google apps
to properly send information back to our application
when the user is done signing in.
Now to add a URL scheme, we're going
to select our app target here, go to Info,
and scroll down to the bottom where it says URL Schemes,
and then click this plus button to add a new one.
The first URL scheme we're going to add is our bundle ID.
You can just add it here in the URL scheme field
and leave everything else as is.
OK, so that one was pretty straightforward.
But the next one we need to add is our OAuth 2.0 client
ID in reverse.
I know, weird, right?
Now, in case you don't have that memorized,
you can actually find it here in the plist file
that we just added to our project.
See?
There it is.
We'll just copy that and paste it here
in the URL Scheme field.
OK, finally, get to write a line of code.
Hurray!
Now, before I get there, since I am doing this in Swift,
I need to add a bridging header file.
So I'm going to use the trick of creating a dummy Objective-C
file, telling Xcode, yes, I would like you to create
a bridging header file for me, and then deleting these two
files.
Now, in my bridging header, I'm just going to import
Google/SignIn.h.
Now I can go into my AppDelegate,
and in my application didFinishLaunching method,
I'm going to make a call to GGLContext.share
dInstance().configureWithError.
This method will look and see what Google/CocoaPod libraries
I have added in our project.
If it finds any, it will attempt to configure them
by reading in constants from that plist file that I added.
In fact, if I run my app right now,
you'll see here in the console that it successfully
configured SignIn.
It'll also report that it didn't bother
trying to configure things like Analytics or Admob,
because we haven't installed those CocoaPods yet.
But if we had, it would try and set those libraries up as well.
Whew, that was an awful lot of setup, but we're done.
Let's get into writing some more code.
There are two delegates you need to be aware of when
you're dealing with Sign-in.
The GIDSignInDelegate is the Delegate
that will be called when the user has finished signing in.
Good candidates for this are your AppDelegate,
your main ViewController, or perhaps
a singleton class that represents your user.
The GIDSignInUIDelegate is the delegate
that our library requires in order to properly display
the embedded WebView.
It's a little weird in that it's required for you to set this,
but it contains all optional methods
that you generally don't need to write if your SignInDelegate
ends up being a ViewController.
So very frequently, you're just going
to say that the UIViewController that
contains your sign-in button is your SignInUIDelegate,
and then not implement any of the optional methods.
That's what I typically do, anyway.
This'll make more sense when you see it in action, trust me.
So let's start with our GIDSignInDelegate.
I think maybe I'll declare that my AppDelegate is
my SignInDelegate.
So I'll add the declaration here,
and I can set it to self here in my application
didFinishLaunching method.
And now I'll need to implement the required
signIn didSignInForUser withError method.
For now, I'm just going to print a few pieces of information
if we succeed and print out the error message if we fail.
Note that I'm still on Swift 1.2,
so I'm using println instead of print.
Oh, and by the way, note that also getting an error here
is pretty common.
The most frequent cause is that the user clicks Cancel instead
of signing in, so don't throw an assertion error
here or anything.
Handle it gracefully.
Oh, and while we're here at the AppDelegate,
I'll also need to handle any incoming URLs.
Remember, the way Google's native apps
send information back to our application
is through an incoming URL.
That's why I had to set those crazy URL
schemes back to the beginning, as you recall.
So we need to make sure we capture these incoming URLs.
And the way to do that is to add a application
openURL sourceApplication annotation method
and pass in all the information along
to the corresponding Google SignIn handleURL method,
kind of like so.
OK, next up, let's go add that GIDSignInUIDelegate
that I was talking about.
I'm going to go into our ViewController
here, because that's where the sign-in button is eventually
going to live.
I'm going to declare that it's our GIDSignInUIDelegate,
and then I will set that down here in our viewDidLoad method.
And then we'll never speak of it again.
Really, that's all I need to do here.
All that's left to do now is actually sign the user in.
Now for that, I'm going to use a button.
Adding a sign-in button using Google's
built-in sign-in button class is pretty straightforward.
I'll just need to add a view to my storyboard here.
We'll make it roughly button shaped,
and maybe we can add some constraints to align it
properly.
Then I'm going to declare that our View's Custom
Class is a GIDSignInButton, and we're done.
No, really, that's it.
Because this View is now a sign-in button,
it knows to start the Google sign-in process
when the user clicks on it.
Heck, let's run this right now in the simulator and see.
So you can see that my mysterious gray rectangle
is now a beautiful blue sign-in button.
And when I click it, Google starts the sign-in process.
You'll also see that I get the embedded ViewController
because there are no native Google apps
to swap to in the simulator.
And when I'm done, you'll get a printout here of those messages
that I put in my didSignInForUserDelegate
method.
Now obviously, it'd be silly to make our user
sign in every time they start our app, which
is what our app currently does.
Most likely in the real world, you're
going to want to cache some of your user's profile information
locally so that when they return,
you remember who they are right away.
However, we're still going to want
to sign them in using Google services as well.
Partly this will ensure that if, say, our user updates
their profile picture or something on Google's side,
that will get retrieved and reflected in our app.
But also, if we're using Google Sign-In in order
to perform other actions using Google services--
and I'll talk about that more in the next video--
we'll be sure to have an up-to-date access token.
To help with this, Google also has a signInSilently method.
This method will try to sign the user
in without showing them any kind of confirmation dialog.
So when we start up our app, we're going to want to call it.
If it works, then our user is signed in,
and we can update any info as needed.
And if it doesn't, well, then we can show our Sign In button.
Now, note that this signInSilently method will only
succeed if our user has signed in to the app
previously on this device, hasn't signed out
in the meantime, and we haven't asked
for any additional permissions or scopes.
So let's go ahead and add this.
So In my ViewController's viewDidLoad method,
I'm just going to make a call to signInSilently.
And now when I start my app, I'll wait a moment,
and I'm once again signed in.
Now that we can sign the user in,
we're going to want to sign them out, at the very least
for testing purposes.
So I'm going to add a simple button here.
Now, I'm just going to create an action to go with it.
And in there, I will call GIDSignIn.shared
Instance.signOut.
Note that no Delegate methods are called here or anything.
It's all done locally and nearly instantly.
And now I can sign out and sign in as much as I'd like.
Finally, it'd be awfully nice if our interface actually
changed when the user signs in.
For that, I'm going to need my AppDelegate, which,
as you recall, is my SignInDelegate,
to talk to my ViewController here.
Obviously there's a lot of ways we could do that.
We could create our own protocol and delegate.
We could send up an NSNotification,
but I think I'll do it by setting
a property in my AppDelegate that
is a method to call when my user has finished signing in.
And then I can have my ViewController
pass an appropriate method to my AppDelegate as that property.
I'm not going to go over all the plumbing here.
You've probably done something like this before.
But when all is said and done, I'm
going to have my AppDelegate tell my ViewController to call
this refreshInterface method.
Now, this method will see if there is a valid currentUser
object on my GIDSignInSharedInstance,
and if so, I can populate a few on-screen labels and images.
Put that together with a few more UI elements,
and you might have something that looks a little like this.
Ah, nice.
So there you go.
That's how you can get started adding Google Sign-In
to your own iOS project.
For more details, please be sure to check out
all the documentation here.
But we're not done yet.
For a few more interesting topics on Sign-In,
follow me to the next video.
Come on!
What?
What are you still doing here?
I'm waiting for you in the next video.
Go on.
Click it.
Right there.
Come on!
We got to go.
There's learning to be had, people!
[MUSIC PLAYING]