Wednesday, March 16, 2016

Google Sign-In for iOS - Display User Email and Profile Picture

Update April 27, 2016:
Step 3 - ViewController.swift is modified with Xcode 7.3 (Swift 2.2).

This post shows how to display the user email and profile picture with Google Sign-In for iOS.

Procedure

1. Create a basic sign-in button with instructions in this tutorial:

Google Sign-In for iOS - Create a GIDSignInButton programmatically in Swift

2. Modify AppDelegate.swift:

//Modify signIn function with didSignInForUser:

    func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
        withError error: NSError!) {
            if (error == nil) {

                let name = user.profile.name
                let email = user.profile.email
                var imageURL = ""
                if user.profile.hasImage {
                    imageURL = user.profile.imageURLWithDimension(100).absoluteString
                }
                NSNotificationCenter.defaultCenter().postNotificationName(
                    "ToggleAuthUINotification",
                    object: nil,
                    userInfo: ["statusText": "Signed in user:\n\(name)""email" : email, "imageURL" : imageURL])

            }
...

//Modify signIn function with didDisconnectWithUser:

    func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
        withError error: NSError!) {
            NSNotificationCenter.defaultCenter().postNotificationName(
                "ToggleAuthUINotification",
                object: nil,
                userInfo: ["statusText": "User has disconnected.", "email" : ""])

    }

3. Modify ViewController.swift:


Update April 27, 2016:

import UIKit

class ViewController: UIViewController, GIDSignInUIDelegate {

    var btnSignIn : GIDSignInButton!
    var btnSignOut : UIButton!
    var btnDisconnect : UIButton!
    var label : UILabel!
    
    var imageView : UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        GIDSignIn.sharedInstance().uiDelegate = self
        
        btnSignIn = GIDSignInButton(frame: CGRectMake(0,0,230,48))
        btnSignIn.center = view.center
        btnSignIn.style = GIDSignInButtonStyle.Standard
        view.addSubview(btnSignIn)
        
        btnSignOut = UIButton(frame: CGRectMake(0,0,100,30))
        btnSignOut.center = CGPointMake(view.center.x, 100)
        btnSignOut.setTitle("Sign Out", forState: UIControlState.Normal)
        btnSignOut.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        btnSignOut.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        btnSignOut.addTarget(self, action: #selector(btnSignOutPressed), forControlEvents: UIControlEvents.TouchUpInside)
        view.addSubview(btnSignOut)
        
        btnDisconnect = UIButton(frame: CGRectMake(0,0,100,30))
        btnDisconnect.center = CGPointMake(view.center.x, 200)
        btnDisconnect.setTitle("Disconnect", forState: UIControlState.Normal)
        btnDisconnect.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        btnDisconnect.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        btnDisconnect.addTarget(self, action: #selector(btnDisconnectPressed), forControlEvents: UIControlEvents.TouchUpInside)
        view.addSubview(btnDisconnect)
        
        label = UILabel(frame: CGRectMake(0,0,300,200))
        label.center = CGPointMake(view.center.x, 430)
        label.numberOfLines = 0
        label.text = "Please Sign in."
        label.textAlignment = NSTextAlignment.Center
        view.addSubview(label)
        
        imageView = UIImageView(frame: CGRectMake(0, 0, 100, 100))
        imageView.center = view.center
        view.addSubview(imageView)
        
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: #selector(receiveToggleAuthUINotification(_:)),
            name: "ToggleAuthUINotification",
            object: nil)
        
        toggleAuthUI()
    }
    
    func btnSignOutPressed() {
        print(GIDSignIn.sharedInstance().currentUser.profile.email)
        print(GIDSignIn.sharedInstance().currentUser.profile.name)
        
        GIDSignIn.sharedInstance().disconnect()
        label.text = "Disconnecting."
    }
    
    func btnDisconnectPressed() {
        label.text = "Signed out."
        toggleAuthUI()
    }
    
    func toggleAuthUI() {
        print("toggleAuthUI")
        if (GIDSignIn.sharedInstance().hasAuthInKeychain()){

            // Signed in
            btnSignIn.hidden = true
            btnSignOut.hidden = false
            btnDisconnect.hidden = false
            
            //NEW!! The code below is required if the app is restarted and already signed in previously.
            if (GIDSignIn.sharedInstance().currentUser == nil) {
                print("no user info")
                GIDSignIn.sharedInstance().signInSilently()
            }
        } else {
            btnSignIn.hidden = false
            btnSignOut.hidden = true
            btnDisconnect.hidden = true
        }
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self,
            name: "ToggleAuthUINotification",
            object: nil)
    }
    
    @objc func receiveToggleAuthUINotification(notification: NSNotification) {
        if (notification.name == "ToggleAuthUINotification") {
            self.toggleAuthUI()
            if notification.userInfo != nil {
                let userInfo:Dictionary<String,String!> =
                notification.userInfo as! Dictionary<String,String!>
                self.label.text = userInfo["statusText"]!+"\n\(userInfo["email"]!)"
                if userInfo["imageURL"] == nil {
                    self.imageView.image = nil
                } else {
                    let url = NSURL(string: userInfo["imageURL"]!)!
                    self.imageView.image = UIImage(data: NSData(contentsOfURL: url)!)
                }
            }
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

=====
Original post March 16, 2016:

//Modified blue texts:


    var imageView : UIImageView!
    
    override func viewDidLoad() {

        ...

        label = UILabel(frame: CGRectMake(0,0,300,200))
        label.center = CGPointMake(view.center.x, 430)
        label.numberOfLines = 0
        label.text = "Please Sign in."
        label.textAlignment = NSTextAlignment.Center
        view.addSubview(label)
        
        imageView = UIImageView(frame: CGRectMake(0, 0, 100, 100))
        imageView.center = view.center
        view.addSubview(imageView)

        ...

//And modify this:


    @objc func receiveToggleAuthUINotification(notification: NSNotification) {
        if (notification.name == "ToggleAuthUINotification") {
            self.toggleAuthUI()
            if notification.userInfo != nil {
                let userInfo:Dictionary<String,String!> =
                notification.userInfo as! Dictionary<String,String!>
                self.label.text = userInfo["statusText"]!+"\n\(userInfo["email"]!)"
                if userInfo["imageURL"] == nil {
                    self.imageView.image = nil
                } else {
                    let url = NSURL(string: userInfo["imageURL"]!)!
                    self.imageView.image = UIImage(data: NSData(contentsOfURL: url)!)
                }
            }
        }

    }
=====

Result

Related Information:

Google Sign-In for iOS - Create a GIDSignInButton programmatically in Swift
Google Sign-In for iOS - Get User Name, Email and Profile Picture without Nofitication
Google Sign-In for iOS - Create a custom sign-in button programmatically
Facebook SDK and Swift - Display User Name and Profile Picture

1 comment: