I am trying to configure scenes to capture a redirect URL after a successful login attempt. I am using OAuth code flow. This is the code I have so far:
ios_app.swift
import SwiftUI
@main
struct ios_appApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
let persistenceController = PersistenceController.shared
@StateObject private var authState = AuthState()
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(authState)
}
}
}
AppDelegate.swift
import UIKit
import AWSMobileClient
import GoogleSignIn
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("AppDelegate: didFinishLaunchingWithOptions")
AWSMobileClient.default().initialize { (userState, error) in
if let userState = userState {
print("UserState: \(userState)")
} else if let error = error {
print("Error initializing AWSMobileClient: \(error.localizedDescription)")
}
}
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
if let error = error {
print("Error restoring previous Google Sign-In: \(error.localizedDescription)")
}
}
return true
}
}
SceneDelegate.swift
import UIKit
import SwiftUI
import GoogleSignIn
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
print("SceneDelegate: scene willConnectTo")
guard let windowScene = (scene as? UIWindowScene) else {
print("SceneDelegate: Invalid windowScene")
return
}
let window = UIWindow(windowScene: windowScene)
let contentView = ContentView().environmentObject(AuthState())
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
print("SceneDelegate: window initialized and visible")
}
func sceneDidDisconnect(_ scene: UIScene) {
print("SceneDelegate: sceneDidDisconnect")
}
func sceneDidBecomeActive(_ scene: UIScene) {
print("SceneDelegate: sceneDidBecomeActive")
}
func sceneWillResignActive(_ scene: UIScene) {
print("SceneDelegate: sceneWillResignActive")
}
func sceneWillEnterForeground(_ scene: UIScene) {
print("SceneDelegate: sceneWillEnterForeground")
}
func sceneDidEnterBackground(_ scene: UIScene) {
print("SceneDelegate: sceneDidEnterBackground")
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
print("SceneDelegate: No URL found in URLContexts")
return
}
print("SceneDelegate: openURLContexts with URL: \(url)")
if GIDSignIn.sharedInstance.handle(url) {
print("SceneDelegate: Google Sign-In handled URL")
return
}
if url.scheme == "myurlscheme" || (url.scheme == "https" && url.host == "mydomain.com" && url.path == "/mobile-auth-callback") {
print("SceneDelegate: Handling auth response for URL: \(url)")
AuthService.shared.handleOAuthCallback(url: url)
} else {
print("SceneDelegate: URL scheme not handled: \(url.scheme ?? "No scheme")")
}
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
print("SceneDelegate: continue userActivity")
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
if let url = userActivity.webpageURL {
handleUniversalLink(url: url)
}
}
}
private func handleUniversalLink(url: URL) {
print("SceneDelegate: Handling universal link: \(url)")
if url.path.contains("/mobile-auth-callback") {
let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
let code = queryItems?.first(where: { $0.name == "code" })?.value
if let code = code {
print("SceneDelegate: Received code: \(code)")
AuthService.shared.exchangeCodeForToken(code: code)
} else {
print("SceneDelegate: No code found, handling email/password callback")
AuthService.shared.handleEmailPasswordCallback(url: url)
}
}
}
}
Also introduced this configuration in Info.plist:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>ios-app.SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
...Other parameters
</dict>
</plist>
I am using the simulator to launch my app and can see AppDelegate related logs but I am not seeing any SceneDelegate logs (I suppose because it is not being initialized nor called).
I have tried restarting the computer/Xcode, clean and rebuild the application but none of the things I tested work.
Is there any part of my code wrong? Any other idea here?