Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use completion handler in delegate method - Swift

I am trying to handle "google sign in" in singleton helper class.

I have LoginHelper, and a method which handles logins with completion handler. As you know Google Sign have delegate methods. When delegate methods are called I need to notify my completion handler. I am not sure, is it possible?

Let's brainstorm together or give me a hand.

My method is as follows;

 @objc func googleLoginPressed(viewController:UIViewController, isLoginSuccessfull:(Bool) -> ())
{        
    GIDSignIn.sharedInstance().signIn()
}
like image 816
erdemgc Avatar asked Apr 28 '18 18:04

erdemgc


People also ask

What is the use of completion handler in Swift?

A completion handler in Swift is a function that calls back when a task completes. This is why it is also called a callback function. A callback function is passed as an argument into another function. When this function completes running a task, it executes the callback function.

What is difference between closure and delegate Swift?

Difference between protocol Delegate and Closures – As we see both method's functionality are the same but there is a difference – In the protocol, we can make more than one function but in Closures, it is a self-contained block of functionality.

What is delegate method in Swift?

The Delegate Pattern in Swift In Swift, a delegate is a controller object with a defined interface that can be used to control or modify the behavior of another object. One example is the UIApplicaitonDelegate in an iOS app.

What does the @escaping keyword do when declaring a completion handler?

To store local variable closure completionHandler to global variable 'completionHandlers we using @escaping` keyword! without @escaping keyword someFunctionWithEscapingClosure returns, local variable completionHandler will remove from memory. @escaping is keep that closure in the memory.


1 Answers

Yes, it is possible

You have to set typeable:

public typealias isCompletion = (_ isConnected: Bool?) -> Void

And add variables like this in class:

var completion: isCompletion?

Your method like this:

func googleLoginPressed(viewController:UIViewController, isLoginSuccessfull:@escaping isCompletion){
    completion = isLoginSuccessfull
    GIDSignIn.sharedInstance().signIn()
}

And after login delegate method will call and then do like this:

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
    if let error = error {
        print("\(error.localizedDescription)")
    } else {
        completion(true)
    }
}

Or

You can do this using protocols:

import UIKit
import GoogleSignIn

/// delegates to handle success and failure response of google sign-in
protocol LoginWithGoogleDelegate: class {
    func didSucceedToSignInFor(user: UserModel)
    func didFailToSignIn(error: Error)
}

/// separate class for google sign-in methods
class LoginWithGoogle: NSObject {

    // MARK: - Properties
    static let sharedInstance = LoginWithGoogle()
    weak var delegate: LoginWithGoogleDelegate?
    var globalViewController: UIViewController?

    // MARK: - Helper Methods
    /**
    configures the settings of google sign-in sdk
     - parameter viewController: it is the view controller on which we have to show the google sign-in screen
    */
    func configureGooglePlus(viewController: UIViewController) {
        globalViewController = viewController
        GIDSignIn.sharedInstance().clientID = Configuration.GoogleSignIn.clientID
        GIDSignIn.sharedInstance().delegate = self
        GIDSignIn.sharedInstance().uiDelegate = self
        GIDSignIn.sharedInstance().signIn()
    }
}

// MARK: - GIDSignInDelegate methods
extension LoginWithGoogle: GIDSignInDelegate {

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
        if let error = error {
            print("\(error.localizedDescription)")
            self.delegate?.didFailToSignIn(error: error)
        } else {
            // Perform any operations on signed in user here.
            var googleUser = UserModel()
            googleUser.googlePlusId = user.userID
            googleUser.googlePlusToken = user.authentication.idToken
            googleUser.fullName = user.profile.name
            googleUser.email = user.profile.email

            //send the user details through LoginWithGoogleDelegate method
            self.delegate?.didSucceedToSignInFor(user: googleUser)
        }
    }

    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
        print("Something Went Wrong")
        self.delegate?.didFailToSignIn(error: error)
    }
}
like image 155
Jogendar Choudhary Avatar answered Oct 05 '22 06:10

Jogendar Choudhary