From abb7be71b62fcf5bf68900105207928adc9eb65a Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 9 Dec 2024 16:01:28 +0530 Subject: [PATCH 1/4] feat: in app sign-in. --- templates/apple/base/requests/oauth.twig | 9 ++-- .../Sources/OAuth/WebAuthComponent.swift.twig | 53 +++++++++++++++---- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/templates/apple/base/requests/oauth.twig b/templates/apple/base/requests/oauth.twig index ede718d7e..ac78529af 100644 --- a/templates/apple/base/requests/oauth.twig +++ b/templates/apple/base/requests/oauth.twig @@ -3,9 +3,12 @@ let callbackScheme = "appwrite-callback-\(client.config["project"] ?? "")" _ = try await withCheckedThrowingContinuation { continuation in - WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in - continuation.resume(with: result) + /// main thread for ASWebAuthenticationPresentationContextProviding + DispatchQueue.main.async { + WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in + continuation.resume(with: result) + } } } - + return true \ No newline at end of file diff --git a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig index a146b28be..d771ce11b 100644 --- a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig +++ b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig @@ -2,8 +2,8 @@ import AsyncHTTPClient import Foundation import NIO -#if canImport(SwiftUI) -import SwiftUI +#if canImport(AuthenticationServices) +import AuthenticationServices #endif /// @@ -13,12 +13,10 @@ import SwiftUI @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, visionOS 1.0, *) public class WebAuthComponent { -#if canImport(SwiftUI) - @Environment(\.openURL) - private static var openURL -#endif - private static var callbacks = [String: (Result) -> Void]() + #if canImport(AuthenticationServices) + private static var currentAuthSession: ASWebAuthenticationSession? + #endif /// /// Authenticate Session with OAuth2 @@ -41,9 +39,29 @@ public class WebAuthComponent { ) { callbacks[callbackScheme] = onComplete - #if canImport(SwiftUI) - openURL(url) - #endif + #if canImport(AuthenticationServices) + currentAuthSession = ASWebAuthenticationSession( + url: url, + callbackURLScheme: callbackScheme + ) { callbackURL, error in + if let error = error { + cleanUp() + } else if let callbackURL = callbackURL { + // handle cookies here itself! + WebAuthComponent.handleIncomingCookie(from: callbackURL) + cleanUp() + } + } + + if let session = currentAuthSession { + /// Indicates that the session should be a private session. + session.prefersEphemeralWebBrowserSession = true + session.presentationContextProvider = PresentationContextProvider.shared + session.start() + } else { + print("Failed to create ASWebAuthenticationSession") + } + #endif } /// @@ -130,5 +148,20 @@ public class WebAuthComponent { callbacks.forEach { (_, callback) in callback(.failure({{ spec.title | caseUcfirst}}Error(message: "User cancelled login."))) } + + #if canImport(AuthenticationServices) + currentAuthSession = nil + #endif + } +} + +#if canImport(AuthenticationServices) +/// Presentation context for the ASWebAuthenticationSession. +class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding { + static let shared = PresentationContextProvider() + + func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { + return ASPresentationAnchor() } } +#endif \ No newline at end of file From 3c0ec71f52e8bd21f458ea90453ba52f6aa0a003 Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 9 Dec 2024 16:05:11 +0530 Subject: [PATCH 2/4] update: comment. --- templates/apple/base/requests/oauth.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/apple/base/requests/oauth.twig b/templates/apple/base/requests/oauth.twig index ac78529af..a91f22414 100644 --- a/templates/apple/base/requests/oauth.twig +++ b/templates/apple/base/requests/oauth.twig @@ -3,7 +3,7 @@ let callbackScheme = "appwrite-callback-\(client.config["project"] ?? "")" _ = try await withCheckedThrowingContinuation { continuation in - /// main thread for ASWebAuthenticationPresentationContextProviding + /// main thread for PresentationContextProvider DispatchQueue.main.async { WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in continuation.resume(with: result) @@ -11,4 +11,4 @@ } } - return true \ No newline at end of file + return true From cf40bb09a155aa903d8a0393ee6e84736be32aea Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 11 Dec 2024 12:29:59 +0530 Subject: [PATCH 3/4] address comments. --- templates/swift/Sources/OAuth/WebAuthComponent.swift.twig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig index d771ce11b..da8630083 100644 --- a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig +++ b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig @@ -161,6 +161,12 @@ class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationCont static let shared = PresentationContextProvider() func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { + if let mainWindow = windowScene.windows.first { + return mainWindow + } + } + return ASPresentationAnchor() } } From 47bcebd9d2bc9b8c7d8afb92a468a50b178850b8 Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 11 Dec 2024 13:36:18 +0530 Subject: [PATCH 4/4] address comments. --- templates/swift/Sources/OAuth/WebAuthComponent.swift.twig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig index da8630083..a44984c98 100644 --- a/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig +++ b/templates/swift/Sources/OAuth/WebAuthComponent.swift.twig @@ -161,10 +161,8 @@ class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationCont static let shared = PresentationContextProvider() func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { - if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { - if let mainWindow = windowScene.windows.first { - return mainWindow - } + if let mainWindow = OSApplication.shared.windows.first { $0.isKeyWindow } { + return mainWindow } return ASPresentationAnchor()