Skip to main content

How to Integrate Google Sign In into Your iOS Apps

Integrate Google Sign

In my last tutorial we worked with the YouTube API, and through the demo application we managed to make requests to that specific Google API. Actually, we created an API key prior to any request, as that key was vital for every request that was about to return data back to our application. This time, we’ll continue working with the Google APIs, and my goal is to show you how to make authorised requests after a user has signed in with the Google in the application.

For this purpose we are going to use a special SDK, named Google Sign-In SDK. This one provides all the necessary classes and functionalities we need in order to:

Add the default Google Sign In button in our app.

Go through the whole user authentication process using the OAuth 2.0 protocol and get the necessary tokens.

Before the Sign-In SDK becomes available, every developer who wanted to allow user authentication in iOS applications and subsequently to perform authorised requests to specific APIs had to manually implement the OAuth 2.0 protocol flow following the rules defined by Google.

Trust me, that was a great hassle, as there were several steps needed to be implemented under certain conditions until the desired access and refresh tokens to be fetched. However, all this is just history now. Things have dramatically changed, as the Sign-In button implements and performs the whole OAuth process behind the scenes.

After a successful sign in, every iOS app can use the access token (and refresh token) to make authorised requests, and most importantly developers can focus on the application logic only. If you want to read more about the OAuth 2.0 protocol, Google provides a nice documentation page for this reason.

We’ll see the details later on. Right before you ask from users to sign in, it’s important to determine the scopes of the API you want to access. A scope actually describes the part of the API (or APIs) that you want your app to have access to.

During the sign in process, Google makes clear to users what they’re about to authorise the app for in a special web page that appears after the credentials have been entered successfully. If you need user authorisation for many scopes, Google suggests to do so incrementally, meaning to ask authorisation for scopes right before the respective features to be used (see more details here).

So, as you understand the first important feature we’ll see here is how to integrate the Sign-In button and how to allow users to sign in. However, doing just that won’t let us make authorised requests, therefore we’ll use the Google+ API as our target API for that purpose. To be more precise, our goal is not to learn how to deal with the Google+ API.

In case you haven’t read the previous tutorial about the YouTube API, I would recommend to do so (or at least the introduction), as everything in this one will come smoother and easier. That doesn’t mean of course that you can’t proceed without it.

Similarly to the previous one, in this tutorial I tried to gather information from various sources in one place too. Right next I give you some useful links that it would be nice to visit.

About the Sign-In SDK for iOS
The Google+ people list API

Demo App Overview

The app that we’ll implement in this post so as to demonstrate all the desired features is parted by two view controllers. In the first one we are going to integrate the Sign-In button, and the app won’t be able to present the second one without a successful sign in from the user. All the sign in and authentication (using the OAuth protocol) process will be handled by the Sign-In SDK.

A special view controller containing a web view will be presented to let users enter the sign-in credentials, and then to accept all the given scopes. Some basic user profile data (such as the name and the email) is asked to be accepted by default. In addition to them, we will ask for authorisation regarding two more scopes, so we can later get the people list from the Google+ circles. All the details will be given later.

In the second view controller there is a tableview and a toolbar with two bar button items. These items will be used to sign out and to disconnect the Google account from the app respectively. There is a difference between these two actions that I will explain when we’ll get to that part.

Regarding the tableview, we are going to have two sections. In the first section we’ll have just two rows, where we’ll display just the user’s real name and the email address. In the second section we’ll list all the people of the Google+ circles that we’ll fetch by making the request to the Google+ API. The only piece of information that we’ll display in this case is the image and the name of each person.

Right next you can see samples of the two view controllers.

Similarly to the most of my tutorials, When you open it, you’ll see that some basic implementation already exists. Among all the code, you will find a method in the ContentViewController named performGetRequest(…). We had implemented and discussed about that method in the previous tutorial (in the YouTube API tutorial), so look there for details about it.

Notice: In case you download the final project to test the app, perform the following actions before the first run:

  1 - Create a client ID and enable the OAuth 2.0 in the Developers Console.
In the GoogleServices-Info.plist file set the proper CLIENT_ID and REVERSED_CLIENT_ID values.

  2 - In the ViewController class set the proper client ID value to the clientIDProperty of the GIDSignIn singleton.

  3 - In the Project > Target > Info > URL Types section, set the proper Bundle ID and Reversed Client ID values to the URL Schemes.

If those steps rise questions, the next two parts will give all the answers you need.

Enabling the OAuth 2.0 Authentication

In the same way we are going to start off here too (with a bit less details). That’s because we have to enable the OAuth 2.0 authentication mechanism so we can use the Google Sign-In button and perform authorised requests.

So, follow the above link and get connected to the Developers Console. The first step is to click to the Create Project blue button, and add a new project that will be connected to our iOS project. For the purposes of this tutorial I named the new project GSignIn, however that’s something you can change if you want.

By creating it you’ll be navigated to another page where you can perform various actions on it. Such an action is to enable the Google+ API, and you’ll manage it by going to the APIs & auth > APIs menu option. Under the Social APIs section you’ll find the Google+ API link, which you have to click. In the next page just click to the Enable API blue button.

Next, go to the APIs & auth > Consent screen option. Here you can specify the information that will be displayed to the default Google’s consent screen that will be shown when we’ll use the Sign-In button to sign in. From all the given fields, the only one that has to be necessarily filled in is the Product Name. So, just type the project’s name and you’re good to go.

Lastly, let’s enable the OAuth 2.0 authentication, so we can access private data by making authorised requests. This time, follow the APIs & auth > Credentials link, and then click to the Create new Client ID button. You are provided with various options in the modal window, but we only care about the Installed application option.

In the details that appear by selecting it, choose (obviously) the iOS application type. As a last step, type the Bundle ID of the app in the respective field. What I used is the com.demo.GSignIn value, but you should change it according to your bundle ID.

You’ll notice that some details regarding the new client ID will appear in the credentials page when you click to the Create Client ID button. All this data shown here is going to be used later during the sign-in process.

For the time being we’ve done our job in the Developers Console, however don’t close the browser/tab yet. We’ll come back shortly to copy the client ID value.

Preparing the Project

In this part we’ll download the Sign-In SDK and we’ll perform all the required configuration in our iOS project so we can successfully sign in later in the app. Note at this point that there are two ways to install and configure the Sign-In SDK; the first one is to use CocoaPods and the second is to go in a more manual way. Here I chose to present the last one, but you can find guidance regarding the first option in the respective documentation.

First of all, the initial step is to get the Sign-In SDK for iOS (you should always make sure that you download the latest version. Once you download it, extract the compressed file’s contents and add both the GoogleSignIn.framework and the GoogleSignIn.bundle files to the project.

You can follow two ways to do that: Either to drag and drop each one to the Project Navigator, or to use the File > Add Files to “GSignIn”… option in Xcode (which I consider to be a safer method; use it if the drag-and-drop method won’t work). At the end, you should see both of them in your Project Navigator.

The Sign-In SDK requires some specific frameworks to be added and linked to the project, therefore this is going to be our next step. In Xcode, go to the Project > Target > General tab > Linked Frameworks and Libraries section, and use the plus button to add the following three frameworks:

    SystemConfiguration.framework
    StoreKit.framework
    AddressBook.framework

Next, we must create a property list (plist) file that will contain two values only: The client ID as it was generated in the Developers Console, and a semi-reversed form of the client ID value. Before I describe the details, go to the File > New > File… menu in Xcode, and select an iOS > Resource > Property List file type to create a new .plist file. It’s really important to name that file GoogleService-Info.plist, as this is the name is used by the SDK to look it up. Once that file is ready and added to the Project Navigator, open it and add two entries. Here are the details:

  1 - In the first one, set the CLIENT_ID key, and in the value field copy-and-paste the generated client ID from the Developers Console.

  2 - In the second, set the REVERSED_CLIENT_ID key, and form the value as follows:
- Begin by writing (or pasting) the com.googleusercontent.apps.string and right after paste just the numerical value of the client ID (i.e. the string right before “.apps.googleusercontent.com”).

In other words, in the CLIENT_ID entry add the com.googleusercontent.apps string right after the numerical value (as it originally is), and in the REVERSED_CLIENT_ID entry use that string as a prefix and don’t append it to the end.

An alternative way to producing the above file, is to let Google prepare it for you. Visit this page, select the proper app name and bundle ID values, and follow the guide. At the end, the GoogleService-Info.plist file will be ready to download, so all you have to do is to add it to the project.

Continuing to the project configuration now, go to the Project > Target > Info > URL Types section in Xcode. Here we must add two URL schemes that the Sign-In SDK needs to be properly set up so as to properly work. Use the plus button, and in the URL Schemes field just type the app bundle ID value (e.g. com.demo.GSignIn). Next, add one more scheme, and add the reversed client ID value to the respective field.

When you get finished with the URL schemes, go to the Project > Target > Build Settings tab. There, scroll down and locate the Linking section, and more specifically the Other Linker Flags entry. Double-click to the (empty) value, and type the -ObjC string. This will make possible to use the Objective-C libraries of the Sign-In SDK in Swift.

Lastly, we are going to need a bridging header file to import the SDK libraries (as I just said it is written in Objective-C). In the starter project you’ve downloaded, you’ll find a bridging header file already being there, named GSignIn-Bridging-Header.h. Click it to open it, and add the following single line:

#import <GoogleSignIn/GoogleSignIn.h>

And with that, all the initial and required configuration is over. I admit that we’ve had more than a few steps to make, but that way we ensure that everything is about to work properly. Let’s write some code now.

Getting Ready to Sign In

According to what I’ve already explained in the introduction, when using the Sign-In button a built-in (to the SDK) view controller is presented with a web view in it, providing us with all the necessary fields to sign in.

Now that all the previous several steps are over, it’s really easy to display the Google Sign-In button and go through the sign in process. All we have to do is to adopt a couple of new protocols, to properly configure a view and set the scopes of the API that we want to have access to. Besides that, working with the Sign-In SDK it couldn’t be easier, as we are not going to create special objects or instances of classes belonging to SDK; we’ll be using just a singleton class named GIDSignIn. But, let’s see everything in the proper order:

Initially, open the ViewController.swift file as our very first step is to adopt the following two protocols:

class ViewController: UIViewController, GIDSignInDelegate, GIDSignInUIDelegate

Of course, let’s not forget that we should make the ViewController class the delegate of the above two, so inside the viewDidLoad function add the next two simple lines:

     override func viewDidLoad()
     {
         super.viewDidLoad()
         // Do any additional setup after loading the view, typically from a nib.

         GIDSignIn.sharedInstance().delegate = self
         GIDSignIn.sharedInstance().uiDelegate = self
      }

We are going to add one more command along with the above two. In this one, we’ll be setting the client ID value explicitly and directly to the GIDSignIn singleton, so open the GoogleService-Info.plist file, copy the value of the CLIENT_ID entry, and paste it right next:

     override func viewDidLoad()
     {
          GIDSignIn.sharedInstance().clientID = "YOUR_CLIENT_ID"
     }

As we’re currently working in the viewDidLoad function and doing some initial setup, now it’s also the best time to specify the required scopes so we can access the API services we want. I’ve already said that a scope defines the exact services of each API that will become available to an application, and every API has a number of scopes that provide access to every aspect of it. In our case we want two things for us to be available: The signed in user’s personal info (name, email), and the list of people existing in all the Google+ circles.

The first part is easily accessible, as there’s no need to specify any scope at all for that; the user’s real name and email address become known by default to the GIDSignIn class when signing in. However, regarding the Google+ API the scopes must be explicitly set, and for getting the list of the people in circles we need the next two scopes:

https://www.googleapis.com/auth/plus.login
https://www.googleapis.com/auth/plus.me

Note: Regardless of the signed in user’s real name and email that is by default available through the GIDSignIn class (you’ll see that in a while), you can get the full user’s Google+ profile and gain access to more information as well. In that case, there are two additional scopes that you should use:

https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile.

However, as we are not going to dive into Google+ API’s details, I only recommend to take a look in the respective official documentation.

Specifying the desired scopes in code-level terms is easy, as all it takes is to append the scope string values to an array named scopes. Here it is:

    override func viewDidLoad()
    {
          GIDSignIn.sharedInstance().scopes.append("https://www.googleapis.com/auth/plus.login")
          GIDSignIn.sharedInstance().scopes.append("https://www.googleapis.com/auth/plus.me")
    }

Finally, let’s focus to the Sign-In button. In the Main.storyboard file and more specifically in the View Controller scene, there’s a view object (a UIView, not a UIButton) in the middle of the scene. Select it, and then set the GIDSignInButton class in the Identity Inspector as shown next.

Now, you can return in the ViewController.swift and change the class of the signInButton IBOutlet property from UIView to GIDSignInButton:

@IBOutlet weak var signInButton: GIDSignInButton!

By performing the last actions, we managed to turn a simple UIView object to the desired Sign-In button, and in the next step we’re about to use it for first time.

Sign In

Previously we adopted two protocols to the ViewController class regarding the Sign-In button, and now it’s time to implement a couple of delegate methods. Here they are:

func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!)
{
}

func signIn(signIn: GIDSignIn!, didDisconnectWithUser user: GIDGoogleUser!, withError error: NSError!)
{
}

It’s easy to understand what each one is for. The first one is called once a sign in process has finished, no matter if it’s successful or not. The second is called when the uses the disconnect button, but we’ll discuss in details about it in the last part, not now.

Focusing in the first delegate method, it’s simple to think what we want from it: To give us access to the protected part of the app after a successful sign in. That means that all we have to do is to check if any error has occurred, and if not, to perform the segue that will take us to the ContentViewController scene. Otherwise, we’ll just display the error message.

func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!)
 {
     if let err = error
     {
          println(error)
     } else {
          performSegueWithIdentifier("idSegueContent", sender: self)
     }
 }

Things so far are pretty clear, as all we have to do is to tap on the Sign-In button, follow the process there, and then the above method will handle the rest.

The most important fact here is that the whole authentication (OAuth) process will take place behind the scenes, and after a successful outcome an access token (managed by the GIDSignIn class) will be stored to the app for future usage. However, maybe you’re wondering what is going to happen with subsequent sign in processes? Do we really have to go through the sign in process each time we use the app? Or there’s another simpler way that will automatically sign us in until we explicitly tell the app we want to sign out?

Thankfully, there is such a way, and is called silent sign in. In that case, the user doesn’t have to take any actions at all. Everything happens in the background, where the GIDSignIn class tries to automatically sign in the user, and if it manages it calls the above delegate method.

If the automatic sign in fails, the delegate method is called, but this time with an error. During the silent sign in, if everything runs without problems, the access and refresh tokens of the OAuth will be refreshed automatically as well.

Having said all the above, let’s head back to the viewDidLoad and let’s enable the silent sign in as shown next:

override func viewDidLoad()
{
     GIDSignIn.sharedInstance().signInSilently()
}

Now, let’s run the app for first time, and let’s go together through all steps until you get signed in. By launching it for first time (Simulator or device, it doesn’t really matter), you’ll see the following screen with an error message at the same time in the console. That’s because the silent sign in failed, so we can just ignore it.

                 

Tap (or click) on the Sign-In button, and wait until the dedicated view controller is presented. Then, enter your credentials to sign in:

In the next step, you’re given with some descriptions regarding all the Google API aspects that our app asks permission for. Actually, what you see here is the result of the scopes that we set earlier, and of course you’ll see different messages for different scopes. The only exceptions are the last two messages, which appear by default (more precisely, the email address scope can be disabled as well).

You’ll notice that next to some scope descriptions there’s a pencil icon. By tapping on any of them, you can perform further customisation or select other sets of options regarding the respective scope. For example, in the second scope above I chose to be the only one knowing that I’ve signed in to this demo app with Google:

Once you go through all the given options, use the Accept button at the bottom side to complete the sign in process. By tapping on it, the OAuth mechanism starts to work, and if nothing bad happens you’ll be taken back to the app while an access token has been fetched in the background.

Actually, you won’t just be taken back to the app, but you’ll be navigated to the ContentViewController view controller. For the time being you won’t see any content, but that’s something we’re about to fix starting from the next part.

Displaying Personal Info

If you followed each step as described in the previous parts properly, then you’ve already managed to sign in to the app using your Google account, so the first big goal of this app has been achieved. Now, in both this and the next part we’ll focus on getting and displaying data. In this part, this data will be taken directly from the GIDSignIn class. In the next part, we’ll make an authorised request to the Google+ API and we’ll fetch the data on the fly.

For our purposes here we’ll make use of two classes that the Sign-In SDK contains and that we haven’t seen so far. These are the GIDGoogleUser and the GIDProfileData. Both of them are accessible through the GIDSignIn singleton as properties. More precisely, there is a property named currentUser that is an instance of the GIDGoogleUser class, and this one in turn contains another property named profile which is an instance of the GIDProfileData class.

Note: You can get detailed information about the above classes, as well as all the other classes and protocols that the Sign-In DK contains in this page. It’s a really informative documentation, so don’t miss it.

Now, let’s focus a bit on our demo application, and more specifically let’s deal with the ContentViewController class. I’ve said already in the application overview part that the tableview in this view controller will have two sections.

In the first one we’ll display two rows with the name and email address of the signed in user, while in the second section we’ll list all the people existing in the Google+ circles of the user. So, let’s dive in the details of the first case, and let’s see how we can get the desired values using the classes I mentioned about previously.

Right now, you can find the following implementation in the ContentViewController.swift file:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
     var cell: UITableViewCell!
     if indexPath.section == 0
      {
           cell = tableView.dequeueReusableCellWithIdentifier("idCellPersonalInfo", forIndexPath:                                                indexPath) as! UITableViewCell
     } else {
          cell = tableView.dequeueReusableCellWithIdentifier("idCellPeople", forIndexPath: indexPath)                                       as! UITableViewCell
    }
 return cell
}

As you can see, in the first case we dequeue the idCellPersonalInfo prototype cell, but as no values are assigned to the text and detail text labels, we’ll do so now. In the following code segment we add the missing implementation in the if body, where we assign the name and email values to the text labels depending on the row index:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell: UITableViewCell!
    if indexPath.section == 0
    {
       cell = tableView.dequeueReusableCellWithIdentifier("idCellPersonalInfo", forIndexPath:                               indexPath) as! UITableViewCell
      if indexPath.row == 0
     {
         cell.textLabel?.text = GIDSignIn.sharedInstance().currentUser.profile.name
         cell.detailTextLabel?.text = "Name"
   } else {
         cell.textLabel?.text = GIDSignIn.sharedInstance().currentUser.profile.email
         cell.detailTextLabel?.text = "Email"
     }
} else {
    cell = tableView.dequeueReusableCellWithIdentifier("idCellPeople", forIndexPath: indexPath)                      as!  UITableViewCell
  }
return cell
}

It’s quite easy to get the user’s basic profile data through the GIDSignIn singleton, don’t you think?

Now, if you run the application once again you’ll see that there’s no need to sign in again, as this will happen silently in the background. Besides that, when the ContentViewController view controller is presented, your basic info is displayed in the first section of the tableview.

Making an Authorised Request

Now that we’ve seen a basic usage of the GIDSignIn class, let’s go ahead to make an authorised request using the access token that the Sign-In button fetched using the OAuth 2.0 protocol. The first thing we’ll do here is to declare (and initialise at the same time) the following array which we’ll use as the datasource in the second section of the tableview:

var peopleDataArray: Array<Dictionary<NSObject, AnyObject>> = []

We’ll get the list of the Google+ circles’ people using the People.list method of the Google+ API. The details can be found in the documentation page of the People: listMethod, and you can even try the request on your own so you can see the results it brings back (make sure to switch on the toggle control right above the form).

https://www.googleapis.com/plus/v1/people/USER_ID/people/COLLECTION?access_token=ACCESS_TOKEN

Besides the access token (last parameter), there are two other required parameters in the above request.

The first one is the user ID that specifies the user for which we want to get the list of people in the Google+ circles. In this example we’ll use the special value me, so we get the people list of our own profile.

The collection parameter is actually the collection of people we want to get, and it accepts either the visible or the connected value. Here we’ll use the first one, meaning that we’ll get all the people existing in the Google+ circles. The connected parameter value returns just the list of people who also use the same app to this one (so obviously it can’t be used).

We are going to define a custom function in the ContentViewController class that we’ll use to make the request. We’ll name it getPeopleList(). Just for the record I have to mention that you’ll find already implemented another method named performGetRequest(…) that performs the actual request in the starter project. We had discussed about it in the my previous tutorial regarding the YouTube API, and now we are reusing it.

Here’s the definition of the new function:

func getPeopleList()
{
}

The logic we’ll follow is starting by specifying the request URL and providing the proper parameters. The last one of course is going to be the authentication access token. Then we’ll make the request, and if we get valid data back without any errors then we’ll proceed as follows (based always on the documentation and the sample results shown above):

 - At first we’ll convert the JSON data into a dictionary object.

 - Among all values in that dictionary, we’ll get an array called items. This one contains the people list.

 - Each item of the items array is also a dictionary. From it we’ll get just two values, the displayName of each item, and the image URL string. Actually, that URL string exists into a sub-dictionary, named image.

 - We’ll store the parsed data from each item into a new dictionary, and then this dictionary will be appended into in the peopleDataArray.

Let’s see the implementation:

func getPeopleList()
{
    let urlString = ("https://www.googleapis.com/plus/v1/people/me/people/visible?access_token=\               (GIDSignIn.sharedInstance().currentUser.authentication.accessToken)")
    let url = NSURL(string: urlString)

    performGetRequest(url, completion: { (data, HTTPStatusCode, error) -> Void in
    if HTTPStatusCode == 200 && error == nil
    {
        let resultsDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error:                   nil) as! Dictionary<NSObject, AnyObject>

        // Get the array with people data dictionaries.
        let peopleArray = resultsDictionary["items"] as! Array<Dictionary<NSObject, AnyObject>>

        // For each item get the display name and download the picture.
        // Store these values in a new dictionary, and then in the peopleDataArray array.
        for item in peopleArray
        {
            var dictionary = Dictionary<NSObject, AnyObject>()
            dictionary["displayName"] = item["displayName"] as! String

            let imageURLString = (item["image"] as! Dictionary<NSObject, AnyObject>)["url"] as!                           String
            dictionary["imageData"] = NSData(contentsOfURL: NSURL(string: imageURLString)!)
           self.peopleDataArray.append(dictionary)
         }
      // Reload the tableview data.
      self.tblContent.reloadData()
  } else {
       println(HTTPStatusCode)
       println(error)
    }
  })
}

Pay attention to the way we access the authentication access token. The authentication property shown above and belongs to the GIDGoogleUser class (see the profile property), is actually an instance of the GIDAuthentication class, also part of the Sign-In SDK. The rest is easy and in accordance to what I described right before. Another interesting part regards the item image. As the only thing we have in the above parsing is the URL as a string value, we use it to grab the actual image data (NSData), which in turn is stored to the dictionary.

dictionary["imageData"] = NSData(contentsOfURL: NSURL(string: imageURLString)!)

Notice also the else case, where (for the sake of the tutorial) we display the error message and the HTTP status code in case of an unwanted situation.

Now, we’ll call the above function in the viewDidLoad:

override func viewDidLoad()
{
    getPeopleList()
}

Finally, let’s update the tableview methods. At first, let’s return the proper number of rows in the second section:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
     if section == 0
     {
        return 2
  } else {
        return peopleDataArray.count
     }
}

Now the cell contents:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell: UITableViewCell!
    if indexPath.section == 0
    {
        ...
 } else {
       cell = tableView.dequeueReusableCellWithIdentifier("idCellPeople", forIndexPath: indexPath)                     as! UITableViewCell
      cell.textLabel?.text = peopleDataArray[indexPath.row]["displayName"] as? String
      cell.imageView?.image = UIImage(data: peopleDataArray[indexPath.row]["imageData"] as!                    NSData)
  }
 return cell
}

We are ready to run the app once again now. This time you’ll see that the people in your Google+ circles are listed in the tableview:

[Image – t40_2_people_sample.png]

Signing Out and Disconnecting

So far we’ve managed to achieve two important goals: To sign in to the app using a Google account, and to perform an authorised request using the access token that was returned to the app as part of the results of the sign in process. However, we can’t still say that we’ve finished, as there’s no option to sign out yet. Apparently that’s what we’ll deal with in this part.

As the title above suggests, we are going to see two things here: How to sign out, and how to disconnect. Using the second option, users can totally disconnect their Google account from the app, while with the first option they just sign out from the app. Of course, in both cases the access and refresh tokens are revoked.

Focusing on our app again, there’s a toolbar with two bar button items in the ContentViewController scene regarding the features we want to implement here. Both button items have been connected to IBAction methods, so let’s see how to sign out first. Doing so it’s easy, as it’s just a matter of one line. Right next you’re given the respective IBAction method implementation:

@IBAction func signOut(sender: AnyObject)
{
    GIDSignIn.sharedInstance().signOut()
    dismissViewControllerAnimated(true, completion: nil)
}

Note that at the end we dismiss the view controller. It would be totally unreasonable to let users have access to a protected area of the app while they have signed out.

If you want, you can test the above functionality. Note however that you have to provide your credentials again the next time you’ll launch the app after you’ve signed out.

Let’s go now to the disconnection. In this case, there’s no need to explicitly sign out users; It’s a process that takes place in the background automatically. Actually, disconnecting a Google account from the app is also just a matter of line, as shown next:

@IBAction func disconnect(sender: AnyObject)
{
     GIDSignIn.sharedInstance().disconnect()
}

Notice that we don’t dismiss the view controller here, and there’s a reason for that. If you remember, in the ViewController class we had defined the following delegate method, but there’s no code yet:

func signIn(signIn: GIDSignIn!, didDisconnectWithUser user: GIDGoogleUser!, withError error: NSError!)
{
}

The above is called every time the disconnect() method of the GIDSignIn class is used, and any logic that comes right after the disconnection must be added at this point. In our case, we just want to dismiss the ContentViewController view controller after it’s been known that the disconnection has finished, but in order to manage this we need an instance of that class. So, let’s do that:

Initially, go back to the ViewController.swift file, and at the top of the class declare the following:

var contentViewController: ContentViewController!

Now, in the prepareForSegue(…) function we’ll instantiate the above object, and then we’ll use it in the previous delegate method:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    if segue.identifier == "idSegueContent"
    {
        contentViewController = segue.destinationViewController as! ContentViewController
    }
}

And here’s the delegate method updated:

func signIn(signIn: GIDSignIn!, didDisconnectWithUser user: GIDGoogleUser!, withError error: NSError!) 
{
     if let err = error
     {
          println(error)
     }
    contentViewController.dismissViewControllerAnimated(true, completion: nil)
}

Notice that in case there’s any error we just print it in the console.

From the user’s perspective there’s no visible difference between the signing out and the disconnection process. However, the important thing is what happens behind the scenes.


Comments

Popular Posts

How I Reduced the Size of My React Native App by 85%

How and Why You Should Do It I borrowed 25$ from my friend to start a Play Store Developer account to put up my first app. I had already created the app, created the assets and published it in the store. Nobody wants to download a todo list app that costs 25mb of bandwidth and another 25 MB of storage space. So today I am going to share with you how I reduced the size of Tet from 25 MB to around 3.5 MB. Size Matters Like any beginner, I wrote my app using Expo, the awesome React Native platform that makes creating native apps a breeze. There is no native setup, you write javascript and Expo builds the binaries for you. I love everything about Expo except the size of the binaries. Each binary weighs around 25 MB regardless of your app. So the first thing I did was to migrate my existing Expo app to React Native. Migrating to React Native react-native init  a new project with the same name Copy the  source  files over from Expo project Install all de...

How to recover data of your Android KeyStore?

These methods can save you by recovering Key Alias and Key Password and KeyStore Password. This dialog becomes trouble to you? You should always keep the keystore file safe as you will not be able to update your previously uploaded APKs on PlayStore. It always need same keystore file for every version releases. But it’s even worse when you have KeyStore file and you forget any credentials shown in above box. But Good thing is you can recover them with certain tricks [Yes, there are always ways]. So let’s get straight to those ways. 1. Check your log files → For  windows  users, Go to windows file explorer C://Users/your PC name/.AndroidStudio1.4 ( your android studio version )\system\log\idea.log.1 ( or any old log number ) Open your log file in Notepad++ or Any text editor, and search for: android.injected.signing and if you are lucky enough then you will start seeing these. Pandroid.injected.signing.store.file = This is  file path where t...

React Native - Text Input

In this chapter, we will show you how to work with  TextInput  elements in React Native. The Home component will import and render inputs. App.js import React from 'react' ; import Inputs from './inputs.js' const App = () => { return ( < Inputs /> ) } export default App Inputs We will define the initial state. After defining the initial state, we will create the  handleEmail  and the  handlePassword  functions. These functions are used for updating state. The  login()  function will just alert the current value of the state. We will also add some other properties to text inputs to disable auto capitalisation, remove the bottom border on Android devices and set a placeholder. inputs.js import React , { Component } from 'react' import { View , Text , TouchableOpacity , TextInput , StyleSheet } from 'react-native' class Inputs extends Component { state = { ...