Introduction
I created a simple app to test enabling Sign In with Google using Observable Objects in a SwiftUI Application. However, the app only functions properly (displaying the signed in user's name and email) with a UIKit App Delegate Life Cycle. The code of the App file for the SwiftUI life cycle and that of the app delegate and scene delegate files of the UIKit App Delegate life cycle should function identical; however, they do not.Project Code
SwiftUI Lift Cycle
AppDelegateCode Block swift import UIKit import SwiftUI import GoogleSignIn class AppDelegate: NSObject, UIApplicationDelegate { /* GoogleDelegate() is the observable object */ let googleDelegate = GoogleDelegate() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { GIDSignIn.sharedInstance()?.clientID = "CLIENT_ID" GIDSignIn.sharedInstance()?.delegate = googleDelegate return true } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance().handle(url) } }
App
Code Block swift @main struct WidgiTubeApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var window: UIWindow? { guard let scene = UIApplication.shared.connectedScenes.first, let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate, let window = windowSceneDelegate.window else { return nil } return window } @Environment(\.scenePhase) private var scenePhase let googleDelegate = (UIApplication.shared.delegate as! AppDelegate).googleDelegate var body: some Scene { WindowGroup { GoogleSignInView() .environmentObject(googleDelegate) }.onChange(of: scenePhase) { (phase) in switch phase { case .active: GIDSignIn.sharedInstance().presentingViewController = window?.rootViewController window?.makeKeyAndVisible() case .inactive: case .background: default: } } } }
Using the SwiftUI Life Cycle the User Is signed in; however, the information does not update in the SwiftUI view. (The view is identical between the SwiftUI Life Cycle and UIKit Application Delegate Life Cycle.)
UIKit Application Delegate Life Cycle
App DelegateDidFinishLaunchingWithOptions
Code Block swift GIDSignIn.sharedInstance().clientID = "CLIENT_ID" GIDSignIn.sharedInstance().delegate = googleDelegate return true
OpenURL
Code Block swift return GIDSignIn.sharedInstance().handle(url)
Scene Delegate
SceneWillConnectTo
Code Block swift let googleDelegate = (UIApplication.shared.delegate as! AppDelegate).googleDelegate let contentView = ContentView().environmentObject(googleDelegate) if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: contentView) GIDSignIn.sharedInstance()?.presentingViewController = window.rootViewController self.window = window window.makeKeyAndVisible() }
Conclusion
Due to this, I have identified that there must be some issue that occurs when adapting the UIKit App Delegate code to the SwiftUI App Code. However, I cannot identify what the issue between the two life cycles is. It is my understanding that anything possible with the UIKit Delegate life cycle should theoretically be possible with SwiftUI. In the mean time, of course, there is no issue continuing with the UIKit Delegate; however, I was hoping to create a SwiftUI app. If anyone could help me identify where the issue lays between these two different life cycles, I would greatly appreciate it. Thanks!