As Uncle Ben says to Peter Parker, “Great power brings, Great responsibility” & this does not apply to SwiftUI.
SwiftUI embraces Great Power but does not embraces Great Responsibility. (yet iOS 13.4.1).
UIKit has served us very well with third party authentication frameworks, Like Google, Facebook, Twitter, but as SwiftUI is new guy in towns, then we must have to have some hacks to bring those things in SwiftUI.
In this (Whatever you may call) I shall walk you through this hack.
In UIKit, we have a GIDSignInButton
for this functionality, so to achieve same functionality we have us UIViewRepresentable
protocol around it.
As per old school way import GoogleSignIn
in AppDelegate
with following line,
GIDSignIn.sharedInstance()?.clientId = "your info.plist's client Id"
Now create a new SwiftUI
file by name GoogleSignInButton
which must conforms to UIViewRepresentable
protocol & with its following variables as shown.
import SwiftUI
import GoogleSignIn
import FirebaseAuth
struct GoogleSignInButton: UIViewRepresentable {
var showAuthAlert: Binding<Bool>
var authError: Binding<Error?>
var onCompletion: ((AuthCredential?) -> Void)
// Here I am using FirebaseAuth for Authetication mechanism, feel free you use your own & just replace type.
init(showAuthAlert: Binding<Bool>, authError: Binding<Error?>, onCompletion: @escaping ((AuthCredential?) -> Void)) {
self.showAuthAlert = showAuthAlert
self.authError = authError
self.onCompletion = onCompletion
}
}
As every SwiftUI
developer is bound to use following functions, so I am gonna also do.
makeUIView(...), updateUIView(...) & makeCoordinator() -> ...
but in my case updateUIView(...)
does not have any effect so I am keeping it as empty rather than removing at all.
func updateUIView(_ uiView: GIDSignInButton, context: UIViewRepresentableContext<GoogleSignInButton>) {
}
func makeUIView(context: Context) -> GIDSignInButton {
// Create instance
let googleSigninButton = GIDSignInButton()
// Set style as wide, you are free here to use your choice
googleSigninButton.style = .wide
// Maksure that there must be a presenting controller as a container
GIDSignIn.sharedInstance()?.presentingViewController = UIApplication.shared.windows.first?.rootViewController
// Below created `Coordinator` type will be delegating object for GIDSignIn
GIDSignIn.sharedInstance()?.delegate = context.coordinator
// & finally return it, because function expectes it.
return googleSigninButton
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
Now here come the magic spell, makeCoordinator() -> ...
requires an instance of type reference so I am bound to use it as subclass of NSObject
& which confirms to GIDSignInDelegate
protocol.
class Coordinator: NSObject, GIDSignInDelegate { ... }
#swiftui #xcode #ios #swift