From f51723725862c3e0dc96929ca8d4c6ee5b3a7873 Mon Sep 17 00:00:00 2001 From: Fran Alarza Date: Mon, 23 Dec 2024 14:20:42 +0100 Subject: [PATCH] feat: create-hosting-window-for-auth-flow --- AppliverySDK/Data/Persisters/Keychain.swift | 4 +- .../Interactors/StartInteractor.swift | 6 +-- .../Managers/AppliveryWebViewManager.swift | 37 +++++++++++++------ .../VideoReport/VideoPreviewScreen.swift | 4 +- AppliverySDK/Services/LoginService.swift | 4 +- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/AppliverySDK/Data/Persisters/Keychain.swift b/AppliverySDK/Data/Persisters/Keychain.swift index 5d4f071..afbec0f 100644 --- a/AppliverySDK/Data/Persisters/Keychain.swift +++ b/AppliverySDK/Data/Persisters/Keychain.swift @@ -40,7 +40,7 @@ final class Keychain: KeychainAccessible { guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) } - logInfo("Password stored for account \(account), password: \(data)") + logInfo("Password stored for account \(account)") } func retrieve(for account: String) throws -> String { @@ -64,7 +64,7 @@ final class Keychain: KeychainAccessible { let password = String(data: data, encoding: .utf8) else { throw KeychainError.unexpectedPasswordData } - logInfo("Retrieved password for account \(account), password: \(password)") + logInfo("Retrieved password for account \(account)") return password } else { throw KeychainError.unhandledError(status: status) diff --git a/AppliverySDK/Interactors/StartInteractor.swift b/AppliverySDK/Interactors/StartInteractor.swift index 9da5fc4..f562143 100644 --- a/AppliverySDK/Interactors/StartInteractor.swift +++ b/AppliverySDK/Interactors/StartInteractor.swift @@ -58,6 +58,7 @@ class StartInteractor { // MARK: Internal Methods func start() { + try? keychain.remove(for: app.bundleId()) logInfo("Applivery is starting... ") logInfo("SDK Version: \(GlobalConfig.shared.app.getSDKVersion())") setupBindings() @@ -126,9 +127,8 @@ private extension StartInteractor { logInfo("Opening auth web view...") let redirectURL = try await loginService.getRedirectURL() await MainActor.run { - if let url = redirectURL, - let rootViewController = UIApplication.shared.windows.first?.rootViewController { - webViewManager.showWebView(url: url, from: rootViewController) + if let url = redirectURL { + webViewManager.showWebView(url: url) } } } catch { diff --git a/AppliverySDK/Managers/AppliveryWebViewManager.swift b/AppliverySDK/Managers/AppliveryWebViewManager.swift index 2edf80e..bad3224 100644 --- a/AppliverySDK/Managers/AppliveryWebViewManager.swift +++ b/AppliverySDK/Managers/AppliveryWebViewManager.swift @@ -10,8 +10,7 @@ import SafariServices import Combine protocol AppliveryWebViewManagerProtocol { - func showWebView(url: URL, from viewController: UIViewController) - func closeWebView() + func showWebView(url: URL) var tokenPublisher: AnyPublisher { get } } @@ -20,6 +19,8 @@ final class AppliveryWebViewManager: NSObject, AppliveryWebViewManagerProtocol { static public let shared = AppliveryWebViewManager() private weak var safariViewController: SFSafariViewController? + private var window: UIWindow? + private let tokenSubject = CurrentValueSubject(nil) var tokenPublisher: AnyPublisher { return tokenSubject.eraseToAnyPublisher() @@ -27,21 +28,17 @@ final class AppliveryWebViewManager: NSObject, AppliveryWebViewManagerProtocol { private override init() {} - func showWebView(url: URL, from viewController: UIViewController) { + func showWebView(url: URL) { let safariVC = SFSafariViewController(url: url) safariVC.delegate = self - viewController.present(safariVC, animated: true, completion: nil) + setNewWindow(viewController: safariVC) + log("Showing web view in a new window") self.safariViewController = safariVC } - func closeWebView() { - safariViewController?.dismiss(animated: true, completion: nil) - safariViewController = nil - } - func urlReceived(url: URL) { if let token = getTokenfromURL(url: url) { - closeWebView() + removeWindow() DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in self?.tokenSubject.send(token) } @@ -52,7 +49,7 @@ final class AppliveryWebViewManager: NSObject, AppliveryWebViewManagerProtocol { extension AppliveryWebViewManager: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { tokenSubject.send(nil) - safariViewController = nil + removeWindow() } } @@ -64,4 +61,22 @@ private extension AppliveryWebViewManager { } return nil } + + func setNewWindow(viewController: UIViewController) { + let hostingViewController = UIViewController() + let newWindow = UIWindow(frame: UIScreen.main.bounds) + newWindow.rootViewController = hostingViewController + newWindow.windowLevel = UIWindow.Level(rawValue: CGFloat.greatestFiniteMagnitude) + newWindow.makeKeyAndVisible() + hostingViewController.present(viewController, animated: true) + + self.window = newWindow + } + + func removeWindow() { + safariViewController?.dismiss(animated: true, completion: nil) + safariViewController = nil + window?.isHidden = true + window = nil + } } diff --git a/AppliverySDK/Modules/VideoReport/VideoPreviewScreen.swift b/AppliverySDK/Modules/VideoReport/VideoPreviewScreen.swift index 50d6b71..2c5bcbc 100644 --- a/AppliverySDK/Modules/VideoReport/VideoPreviewScreen.swift +++ b/AppliverySDK/Modules/VideoReport/VideoPreviewScreen.swift @@ -53,8 +53,8 @@ struct VideoPreviewScreen: View { self.presentationMode.wrappedValue.dismiss() }, label: { Text("X") - .font(.system(size: 20)) - .foregroundColor(.black) + .font(.system(size: 20, weight: .bold)) + .foregroundColor(.blue) }), trailing: Button(action: { diff --git a/AppliverySDK/Services/LoginService.swift b/AppliverySDK/Services/LoginService.swift index ebe79c8..6ea0447 100644 --- a/AppliverySDK/Services/LoginService.swift +++ b/AppliverySDK/Services/LoginService.swift @@ -87,8 +87,8 @@ final class LoginService: LoginServiceProtocol { do { logInfo("Opening auth web view...") let redirectURL = try await loginRepository.getRedirctURL() - if let url = redirectURL, let rootViewController = UIApplication.shared.windows.first?.rootViewController { - webViewManager.showWebView(url: url, from: rootViewController) + if let url = redirectURL { + webViewManager.showWebView(url: url) } } catch { log("Error obtaining redirect URL: \(error.localizedDescription)")