diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index aa1e880..214f5b9 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,7 +1,7 @@ PODS: - boost (1.76.0) - CocoaAsyncSocket (7.6.5) - - descope-react-native (0.6.2): + - descope-react-native (0.6.3): - RCT-Folly (= 2021.07.22.00) - React-Core - DoubleConversion (1.1.6) @@ -662,7 +662,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 57d2868c099736d80fcd648bf211b4431e51a558 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - descope-react-native: 4c3147e228c0e6099dbb507e08d81ac39acc0985 + descope-react-native: 79e1f9ef902efd20dad890ee647b1f0be2951d1d DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 FBReactNativeSpec: 3fc2d478e1c4b08276f9dd9128f80ec6d5d85c1f diff --git a/ios/DescopeReactNative.swift b/ios/DescopeReactNative.swift index e582821..257ae39 100644 --- a/ios/DescopeReactNative.swift +++ b/ios/DescopeReactNative.swift @@ -4,6 +4,7 @@ import AuthenticationServices private let redirectScheme = "descopeauth" private let redirectURL = "\(redirectScheme)://flow" +private let maxKeyWindowAttempts = 10 @objc(DescopeReactNative) class DescopeReactNative: NSObject { @@ -35,8 +36,8 @@ class DescopeReactNative: NSObject { do { let initialURL = try prepareInitialRequest(for: flowURL, with: codeChallenge) - DispatchQueue.main.async { - self.startFlow(initialURL) + Task { @MainActor in + await self.startFlow(initialURL) } } catch { reject("flow_setup", "Flow setup failed", error) @@ -53,19 +54,16 @@ class DescopeReactNative: NSObject { } guard let resumeURL = components.url else { return reject("flow_resume", "unable to construct resuming url params", nil) } - - DispatchQueue.main.async { - self.startFlow(resumeURL) + Task { @MainActor in + await self.startFlow(resumeURL) } resolve(nil) } @MainActor - private func startFlow(_ url: URL) { - guard defaultContextProvider.findKeyWindow() != nil else { - reject?("flow_failed", "unable to find key window", nil) - return - } + private func startFlow(_ url: URL) async { + await defaultContextProvider.waitKeyWindow(attempts: maxKeyWindowAttempts) + let session = ASWebAuthenticationSession(url: url, callbackURLScheme: redirectScheme) { [self] callbackURL, error in if let error { switch error { @@ -157,6 +155,15 @@ private func prepareInitialRequest(for flowURL: String, with codeChallenge: Stri } private class DefaultContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding { + func waitKeyWindow(attempts: Int) async { + for _ in 1...attempts { + if let window = findKeyWindow() { + return + } + try? await Task.sleep(nanoseconds: 100 * NSEC_PER_MSEC) + } + } + func findKeyWindow() -> UIWindow? { let scene = UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } @@ -170,7 +177,7 @@ private class DefaultContextProvider: NSObject, ASWebAuthenticationPresentationC } func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { - return ASPresentationAnchor() + return findKeyWindow() ?? ASPresentationAnchor() } } diff --git a/package.json b/package.json index 8830c8d..a79aef3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@descope/react-native-sdk", - "version": "0.6.2", + "version": "0.6.3", "description": "The Descope SDK for React-Native", "main": "lib/commonjs/index", "module": "lib/module/index",