From facc11ad7919d62b2570fe094f36b5f2cc88df6e Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Mon, 16 Dec 2024 17:16:31 +0100 Subject: [PATCH 1/8] WIP Signed-off-by: Milen Pivchev --- Nextcloud.xcodeproj/project.pbxproj | 14 ++- iOSClient/Login/NCLogin.swift | 90 ++++++++++++++++++-- iOSClient/Login/{ => Poll}/NCLoginPoll.swift | 76 ++--------------- iOSClient/Login/Poll/NCLoginPollModel.swift | 64 ++++++++++++++ 4 files changed, 167 insertions(+), 77 deletions(-) rename iOSClient/Login/{ => Poll}/NCLoginPoll.swift (55%) create mode 100644 iOSClient/Login/Poll/NCLoginPollModel.swift diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 8409f7a395..ab063b2b6f 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -168,6 +168,7 @@ F3BB464D2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F3BB464C2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib */; }; F3BB46522A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3BB46512A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift */; }; F3BB46542A3A1E9D00461F6E /* CCCellMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3BB46532A3A1E9D00461F6E /* CCCellMore.swift */; }; + F3CA33842D10726E00672333 /* NCLoginPollModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3CA33832D10726E00672333 /* NCLoginPollModel.swift */; }; F3E173B02C9AF637006D177A /* ScreenAwakeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */; }; F3E173C02C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; }; F3E173C12C9B1067006D177A /* AwakeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E173BF2C9B1067006D177A /* AwakeMode.swift */; }; @@ -1223,6 +1224,7 @@ F3BB464C2A39ADCC00461F6E /* NCMoreAppSuggestionsCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCMoreAppSuggestionsCell.xib; sourceTree = ""; }; F3BB46512A39EC4900461F6E /* NCMoreAppSuggestionsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMoreAppSuggestionsCell.swift; sourceTree = ""; }; F3BB46532A3A1E9D00461F6E /* CCCellMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCCellMore.swift; sourceTree = ""; }; + F3CA33832D10726E00672333 /* NCLoginPollModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginPollModel.swift; sourceTree = ""; }; F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenAwakeManager.swift; sourceTree = ""; }; F3E173BF2C9B1067006D177A /* AwakeMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AwakeMode.swift; sourceTree = ""; }; F3EF2E0B2BFCF3810025EF46 /* NCLoginPoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginPoll.swift; sourceTree = ""; }; @@ -2038,6 +2040,15 @@ path = Cells; sourceTree = ""; }; + F3CA33802D106FF900672333 /* Poll */ = { + isa = PBXGroup; + children = ( + F3EF2E0B2BFCF3810025EF46 /* NCLoginPoll.swift */, + F3CA33832D10726E00672333 /* NCLoginPollModel.swift */, + ); + path = Poll; + sourceTree = ""; + }; F3E173BE2C9B1057006D177A /* ScreenAwakeManager */ = { isa = PBXGroup; children = ( @@ -2733,6 +2744,7 @@ F7BFFA621A24D7300044ED85 /* Login */ = { isa = PBXGroup; children = ( + F3CA33802D106FF900672333 /* Poll */, F702F2F025EE5CDA008F8E80 /* NCLogin.storyboard */, F702F2F625EE5CEC008F8E80 /* NCLogin.swift */, F738D48F2756740100CD1D38 /* NCLoginNavigationController.swift */, @@ -2740,7 +2752,6 @@ F7AE00F4230D5F9E007ACF8A /* NCLoginProvider.swift */, F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */, F7BC287F26663F85004D46C5 /* NCViewCertificateDetails.swift */, - F3EF2E0B2BFCF3810025EF46 /* NCLoginPoll.swift */, ); path = Login; sourceTree = ""; @@ -4287,6 +4298,7 @@ F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */, F77DD6A82C5CC093009448FB /* NCSession.swift in Sources */, F702F30825EE5D47008F8E80 /* NCPopupViewController.swift in Sources */, + F3CA33842D10726E00672333 /* NCLoginPollModel.swift in Sources */, F733598125C1C188002ABA72 /* NCAskAuthorization.swift in Sources */, 370D26AF248A3D7A00121797 /* NCCellProtocol.swift in Sources */, F768822C2C0DD1E7001CF441 /* NCKeychain.swift in Sources */, diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index 8ee3813b07..3b3356712a 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -26,6 +26,7 @@ import UIKit import NextcloudKit import SwiftEntryKit import SwiftUI +import SafariServices class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { @IBOutlet weak var imageBrand: UIImageView! @@ -45,11 +46,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { private var activeTextField = UITextField() private var shareAccounts: [NKShareAccounts.DataAccounts]? - - var loginFlowV2Token = "" - var loginFlowV2Endpoint = "" - var loginFlowV2Login = "" - + /// The URL that will show up on the URL field when this screen appears var urlBase = "" @@ -62,6 +59,10 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { private var p12Data: Data? private var p12Password: String? + private var useInAppBrowser = false + + var pollTimer: DispatchSourceTimer? + // MARK: - View Life Cycle override func viewDidLoad() { @@ -204,6 +205,12 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } } + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + pollTimer?.cancel() + } + private func handleLoginWithAppConfig() { let accountCount = NCManageDatabase.shared.getAccounts()?.count ?? 0 @@ -332,16 +339,30 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { if let host = URL(string: url)?.host { NCNetworking.shared.writeCertificate(host: host) } - NextcloudKit.shared.getLoginFlowV2(serverUrl: url) { token, endpoint, login, _, error in + NextcloudKit.shared.getLoginFlowV2(serverUrl: url) { [self] token, endpoint, login, _, error in self.loginButton.isEnabled = true // Login Flow V2 if error == .success, let token, let endpoint, let login { - let vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login)) - self.present(vc, animated: true) + + guard let url = URL(string: login) else { return } + let vc: UIViewController + + if useInAppBrowser { + vc = SFSafariViewController(url: url) + } else { + vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login, model: NCLoginPollModel())) + } + + present(vc, animated: true) + +// let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController +// controller?.present(sfSafariController, animated: true) +// self.present(vc, animated: true) + poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) } else if serverInfo.versionMajor < NCGlobal.shared.nextcloudVersion12 { // No login flow available let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: NSLocalizedString("_webflow_not_available_", comment: ""), preferredStyle: .alert) alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) - self.present(alertController, animated: true, completion: { }) + present(alertController, animated: true, completion: { }) } } case .failure(let error): @@ -491,4 +512,55 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { alertWrongPassword.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default)) present(alertWrongPassword, animated: true) } + + func poll(loginFlowV2Token: String, loginFlowV2Endpoint: String, loginFlowV2Login: String) { + let queue = DispatchQueue.global(qos: .background) + pollTimer = DispatchSource.makeTimerSource(queue: queue) + + guard let timer = pollTimer else { return } + + timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1)) + timer.setEventHandler(handler: { + DispatchQueue.main.async { + let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController + NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint) { server, loginName, appPassword, _, error in + if error == .success, let urlBase = server, let user = loginName, let appPassword { +// self.isLoading = true + NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in + if error == .success { +// self.account = account +// if value { + let window = UIApplication.shared.firstWindow + if let controller = window?.rootViewController as? NCMainTabBarController { + controller.account = account + controller.dismiss(animated: true, completion: nil) + } else { + if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController { + controller.account = account + controller.modalPresentationStyle = .fullScreen + controller.view.alpha = 0 + + window?.rootViewController = controller + window?.makeKeyAndVisible() + + if let scene = window?.windowScene { + SceneManager.shared.register(scene: scene, withRootViewController: controller) + } + + UIView.animate(withDuration: 0.5) { + controller.view.alpha = 1 + } + } +// } + } +// self.pollFinished = true + } + } + } + } + } + }) + + timer.resume() + } } diff --git a/iOSClient/Login/NCLoginPoll.swift b/iOSClient/Login/Poll/NCLoginPoll.swift similarity index 55% rename from iOSClient/Login/NCLoginPoll.swift rename to iOSClient/Login/Poll/NCLoginPoll.swift index 99e513a56e..fde9073046 100644 --- a/iOSClient/Login/NCLoginPoll.swift +++ b/iOSClient/Login/Poll/NCLoginPoll.swift @@ -31,7 +31,7 @@ struct NCLoginPoll: View { var cancelButtonDisabled = false - @ObservedObject private var loginManager = LoginManager() + @ObservedObject var model: NCLoginPollModel @Environment(\.dismiss) private var dismiss var body: some View { @@ -50,12 +50,12 @@ struct NCLoginPoll: View { Button(NSLocalizedString("_cancel_", comment: "")) { dismiss() } - .disabled(loginManager.isLoading || cancelButtonDisabled) + .disabled(model.isLoading || cancelButtonDisabled) .buttonStyle(.bordered) .tint(.white) Button(NSLocalizedString("_retry_", comment: "")) { - loginManager.openLoginInBrowser() + model.openLoginInBrowser() } .buttonStyle(.borderedProminent) .foregroundStyle(Color(NCBrandColor.shared.customer)) @@ -64,15 +64,15 @@ struct NCLoginPoll: View { .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) - .onChange(of: loginManager.pollFinished) { value in + .onChange(of: model.pollFinished) { value in if value { let window = UIApplication.shared.firstWindow if let controller = window?.rootViewController as? NCMainTabBarController { - controller.account = loginManager.account + controller.account = model.account controller.dismiss(animated: true, completion: nil) } else { if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController { - controller.account = loginManager.account + controller.account = model.account controller.modalPresentationStyle = .fullScreen controller.view.alpha = 0 @@ -92,74 +92,16 @@ struct NCLoginPoll: View { } .background(Color(NCBrandColor.shared.customer)) .onAppear { - loginManager.configure(loginFlowV2Token: loginFlowV2Token, loginFlowV2Endpoint: loginFlowV2Endpoint, loginFlowV2Login: loginFlowV2Login) +// model.configure(loginFlowV2Token: loginFlowV2Token, loginFlowV2Endpoint: loginFlowV2Endpoint, loginFlowV2Login: loginFlowV2Login) if !isRunningForPreviews { - loginManager.openLoginInBrowser() + model.openLoginInBrowser() } } - .onDisappear { - loginManager.onDisappear() - } .interactiveDismissDisabled() } } #Preview { - NCLoginPoll(loginFlowV2Token: "", loginFlowV2Endpoint: "", loginFlowV2Login: "") -} - -private class LoginManager: ObservableObject { - var loginFlowV2Token = "" - var loginFlowV2Endpoint = "" - var loginFlowV2Login = "" - - @Published var pollFinished = false - @Published var isLoading = false - @Published var account = "" - - var timer: DispatchSourceTimer? - - func configure(loginFlowV2Token: String, loginFlowV2Endpoint: String, loginFlowV2Login: String) { - self.loginFlowV2Token = loginFlowV2Token - self.loginFlowV2Endpoint = loginFlowV2Endpoint - self.loginFlowV2Login = loginFlowV2Login - - poll() - } - - func poll() { - let queue = DispatchQueue.global(qos: .background) - timer = DispatchSource.makeTimerSource(queue: queue) - - guard let timer = timer else { return } - - timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1)) - timer.setEventHandler(handler: { - DispatchQueue.main.async { - let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController - NextcloudKit.shared.getLoginFlowV2Poll(token: self.loginFlowV2Token, endpoint: self.loginFlowV2Endpoint) { server, loginName, appPassword, _, error in - if error == .success, let urlBase = server, let user = loginName, let appPassword { - self.isLoading = true - NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in - if error == .success { - self.account = account - self.pollFinished = true - } - } - } - } - } - }) - - timer.resume() - } - - func onDisappear() { - timer?.cancel() - } - - func openLoginInBrowser() { - UIApplication.shared.open(URL(string: loginFlowV2Login)!) - } + NCLoginPoll(loginFlowV2Token: "", loginFlowV2Endpoint: "", loginFlowV2Login: "", model: NCLoginPollModel()) } diff --git a/iOSClient/Login/Poll/NCLoginPollModel.swift b/iOSClient/Login/Poll/NCLoginPollModel.swift new file mode 100644 index 0000000000..fc19a7e1e4 --- /dev/null +++ b/iOSClient/Login/Poll/NCLoginPollModel.swift @@ -0,0 +1,64 @@ +// +// NCLoginPollModel.swift +// Nextcloud +// +// Created by Milen Pivchev on 16.12.24. +// Copyright © 2024 Marino Faggiana. All rights reserved. +// + +import Foundation + +class NCLoginPollModel: ObservableObject { +// var loginFlowV2Token = "" +// var loginFlowV2Endpoint = "" +// var loginFlowV2Login = "" + + @Published var pollFinished = false + @Published var isLoading = false + @Published var account = "" + + var timer: DispatchSourceTimer? + + func configure() { +// self.loginFlowV2Token = loginFlowV2Token +// self.loginFlowV2Endpoint = loginFlowV2Endpoint +// self.loginFlowV2Login = loginFlowV2Login +// +// poll() + } + + func poll() { + let queue = DispatchQueue.global(qos: .background) + timer = DispatchSource.makeTimerSource(queue: queue) + + guard let timer = timer else { return } + + timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1)) + timer.setEventHandler(handler: { + DispatchQueue.main.async { + let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController + NextcloudKit.shared.getLoginFlowV2Poll(token: self.loginFlowV2Token, endpoint: self.loginFlowV2Endpoint) { server, loginName, appPassword, _, error in + if error == .success, let urlBase = server, let user = loginName, let appPassword { + self.isLoading = true + NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in + if error == .success { + self.account = account + self.pollFinished = true + } + } + } + } + } + }) + + timer.resume() + } + + func onDisappear() { + timer?.cancel() + } + + func openLoginInBrowser() { + UIApplication.shared.open(URL(string: loginFlowV2Login)!) + } +} From eb56c26c3ec6aada71276b32640ec8640417ebcf Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Mon, 16 Dec 2024 18:45:26 +0100 Subject: [PATCH 2/8] WIP Signed-off-by: Milen Pivchev --- iOSClient/Login/NCLogin.swift | 76 ++++++++++----------- iOSClient/Login/Poll/NCLoginPoll.swift | 42 ++---------- iOSClient/Login/Poll/NCLoginPollModel.swift | 53 +++++--------- 3 files changed, 60 insertions(+), 111 deletions(-) diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index 3b3356712a..1c333a442c 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -46,7 +46,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { private var activeTextField = UITextField() private var shareAccounts: [NKShareAccounts.DataAccounts]? - + /// The URL that will show up on the URL field when this screen appears var urlBase = "" @@ -59,10 +59,12 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { private var p12Data: Data? private var p12Password: String? - private var useInAppBrowser = false + private var useInAppBrowser = true var pollTimer: DispatchSourceTimer? + var ncLoginPollModel = NCLoginPollModel() + // MARK: - View Life Cycle override func viewDidLoad() { @@ -183,11 +185,11 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { enforceServersButton.menu = .init(title: NSLocalizedString("_servers_", comment: ""), children: actions) enforceServersButton.showsMenuAsPrimaryAction = true enforceServersButton.configuration?.titleTextAttributesTransformer = - UIConfigurationTextAttributesTransformer { incoming in - var outgoing = incoming - outgoing.font = UIFont.systemFont(ofSize: 13) - return outgoing - } + UIConfigurationTextAttributesTransformer { incoming in + var outgoing = incoming + outgoing.font = UIFont.systemFont(ofSize: 13) + return outgoing + } } } @@ -290,7 +292,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } @IBAction func actionQRCode(_ sender: Any) { - let qrCode = NCLoginQRCode(delegate: self) qrCode.scan() } @@ -350,15 +351,12 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { if useInAppBrowser { vc = SFSafariViewController(url: url) } else { - vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login, model: NCLoginPollModel())) + vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Login: login, model: ncLoginPollModel)) } - present(vc, animated: true) - -// let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController -// controller?.present(sfSafariController, animated: true) -// self.present(vc, animated: true) poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) + + present(vc, animated: true) } else if serverInfo.versionMajor < NCGlobal.shared.nextcloudVersion12 { // No login flow available let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: NSLocalizedString("_webflow_not_available_", comment: ""), preferredStyle: .alert) alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) @@ -494,7 +492,6 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { let alertEnterPassword = UIAlertController(title: NSLocalizedString("_client_cert_enter_password_", comment: ""), message: "", preferredStyle: .alert) alertEnterPassword.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel, handler: nil)) alertEnterPassword.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in - // let documentProviderMenu = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.pkcs12]) NCNetworking.shared.p12Data = try? Data(contentsOf: urls[0]) NCNetworking.shared.p12Password = alertEnterPassword.textFields?[0].text self.login() @@ -523,37 +520,34 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { timer.setEventHandler(handler: { DispatchQueue.main.async { let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController - NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint) { server, loginName, appPassword, _, error in + NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint) { [self] server, loginName, appPassword, _, error in if error == .success, let urlBase = server, let user = loginName, let appPassword { -// self.isLoading = true + ncLoginPollModel.isLoading = true + NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in if error == .success { -// self.account = account -// if value { - let window = UIApplication.shared.firstWindow - if let controller = window?.rootViewController as? NCMainTabBarController { + let window = UIApplication.shared.firstWindow + if let controller = window?.rootViewController as? NCMainTabBarController { + controller.account = account + controller.dismiss(animated: true, completion: nil) + } else { + if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController { controller.account = account - controller.dismiss(animated: true, completion: nil) - } else { - if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController { - controller.account = account - controller.modalPresentationStyle = .fullScreen - controller.view.alpha = 0 - - window?.rootViewController = controller - window?.makeKeyAndVisible() - - if let scene = window?.windowScene { - SceneManager.shared.register(scene: scene, withRootViewController: controller) - } - - UIView.animate(withDuration: 0.5) { - controller.view.alpha = 1 - } + controller.modalPresentationStyle = .fullScreen + controller.view.alpha = 0 + + window?.rootViewController = controller + window?.makeKeyAndVisible() + + if let scene = window?.windowScene { + SceneManager.shared.register(scene: scene, withRootViewController: controller) } -// } + + UIView.animate(withDuration: 0.5) { + controller.view.alpha = 1 + } + } } -// self.pollFinished = true } } } @@ -564,3 +558,5 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { timer.resume() } } + + diff --git a/iOSClient/Login/Poll/NCLoginPoll.swift b/iOSClient/Login/Poll/NCLoginPoll.swift index fde9073046..dc5892aaa3 100644 --- a/iOSClient/Login/Poll/NCLoginPoll.swift +++ b/iOSClient/Login/Poll/NCLoginPoll.swift @@ -25,11 +25,11 @@ import NextcloudKit import SwiftUI struct NCLoginPoll: View { - let loginFlowV2Token: String - let loginFlowV2Endpoint: String + // let loginFlowV2Token: String + // let loginFlowV2Endpoint: String let loginFlowV2Login: String - var cancelButtonDisabled = false + // var cancelButtonDisabled = false @ObservedObject var model: NCLoginPollModel @Environment(\.dismiss) private var dismiss @@ -50,12 +50,12 @@ struct NCLoginPoll: View { Button(NSLocalizedString("_cancel_", comment: "")) { dismiss() } - .disabled(model.isLoading || cancelButtonDisabled) + .disabled(model.isLoading) .buttonStyle(.bordered) .tint(.white) Button(NSLocalizedString("_retry_", comment: "")) { - model.openLoginInBrowser() + model.openLoginInBrowser(loginFlowV2Login: loginFlowV2Login) } .buttonStyle(.borderedProminent) .foregroundStyle(Color(NCBrandColor.shared.customer)) @@ -64,38 +64,10 @@ struct NCLoginPoll: View { .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) - .onChange(of: model.pollFinished) { value in - if value { - let window = UIApplication.shared.firstWindow - if let controller = window?.rootViewController as? NCMainTabBarController { - controller.account = model.account - controller.dismiss(animated: true, completion: nil) - } else { - if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController { - controller.account = model.account - controller.modalPresentationStyle = .fullScreen - controller.view.alpha = 0 - - window?.rootViewController = controller - window?.makeKeyAndVisible() - - if let scene = window?.windowScene { - SceneManager.shared.register(scene: scene, withRootViewController: controller) - } - - UIView.animate(withDuration: 0.5) { - controller.view.alpha = 1 - } - } - } - } - } .background(Color(NCBrandColor.shared.customer)) .onAppear { -// model.configure(loginFlowV2Token: loginFlowV2Token, loginFlowV2Endpoint: loginFlowV2Endpoint, loginFlowV2Login: loginFlowV2Login) - if !isRunningForPreviews { - model.openLoginInBrowser() + model.openLoginInBrowser(loginFlowV2Login: loginFlowV2Login) } } .interactiveDismissDisabled() @@ -103,5 +75,5 @@ struct NCLoginPoll: View { } #Preview { - NCLoginPoll(loginFlowV2Token: "", loginFlowV2Endpoint: "", loginFlowV2Login: "", model: NCLoginPollModel()) + NCLoginPoll(loginFlowV2Login: "", model: NCLoginPollModel()) } diff --git a/iOSClient/Login/Poll/NCLoginPollModel.swift b/iOSClient/Login/Poll/NCLoginPollModel.swift index fc19a7e1e4..fe608856e7 100644 --- a/iOSClient/Login/Poll/NCLoginPollModel.swift +++ b/iOSClient/Login/Poll/NCLoginPollModel.swift @@ -9,15 +9,23 @@ import Foundation class NCLoginPollModel: ObservableObject { + // var loginFlowV2Token = "" // var loginFlowV2Endpoint = "" -// var loginFlowV2Login = "" - @Published var pollFinished = false +// @Published var pollFinished = false @Published var isLoading = false - @Published var account = "" +// @Published var account = "" + +// var timer: DispatchSourceTimer? - var timer: DispatchSourceTimer? +// init(delegate: NCLoginPoll, pollFinished: Bool = false, isLoading: Bool = false, account: String = "", timer: DispatchSourceTimer? = nil) { +// self.delegate = delegate +// self.pollFinished = pollFinished +// self.isLoading = isLoading +// self.account = account +// self.timer = timer +// } func configure() { // self.loginFlowV2Token = loginFlowV2Token @@ -27,38 +35,11 @@ class NCLoginPollModel: ObservableObject { // poll() } - func poll() { - let queue = DispatchQueue.global(qos: .background) - timer = DispatchSource.makeTimerSource(queue: queue) - - guard let timer = timer else { return } - - timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1)) - timer.setEventHandler(handler: { - DispatchQueue.main.async { - let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController - NextcloudKit.shared.getLoginFlowV2Poll(token: self.loginFlowV2Token, endpoint: self.loginFlowV2Endpoint) { server, loginName, appPassword, _, error in - if error == .success, let urlBase = server, let user = loginName, let appPassword { - self.isLoading = true - NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in - if error == .success { - self.account = account - self.pollFinished = true - } - } - } - } - } - }) - - timer.resume() - } - - func onDisappear() { - timer?.cancel() - } - - func openLoginInBrowser() { + func openLoginInBrowser(loginFlowV2Login: String = "") { UIApplication.shared.open(URL(string: loginFlowV2Login)!) } } + +protocol NCLoginDelegate: AnyObject { + func pollDidStart() +} From 027f9d9b8660ce537177f0ad01ef1a2026e915a8 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Tue, 17 Dec 2024 09:57:24 +0100 Subject: [PATCH 3/8] WIP Signed-off-by: Milen Pivchev --- iOSClient/Login/NCLogin.swift | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index 1c333a442c..a821b7f2eb 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -207,11 +207,11 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } } - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - - pollTimer?.cancel() - } +// override func viewDidDisappear(_ animated: Bool) { +// super.viewDidDisappear(animated) +// +// pollTimer?.cancel() +// } private func handleLoginWithAppConfig() { let accountCount = NCManageDatabase.shared.getAccounts()?.count ?? 0 @@ -344,17 +344,17 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { self.loginButton.isEnabled = true // Login Flow V2 if error == .success, let token, let endpoint, let login { - guard let url = URL(string: login) else { return } let vc: UIViewController + poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) + if useInAppBrowser { vc = SFSafariViewController(url: url) } else { vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Login: login, model: ncLoginPollModel)) } - poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) present(vc, animated: true) } else if serverInfo.versionMajor < NCGlobal.shared.nextcloudVersion12 { // No login flow available @@ -558,5 +558,3 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { timer.resume() } } - - From 8319a494f6b9bc27976d94819ea6c0923e8b95a4 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Tue, 17 Dec 2024 10:45:14 +0100 Subject: [PATCH 4/8] WIP Signed-off-by: Milen Pivchev --- Nextcloud.xcodeproj/project.pbxproj | 8 +++- iOSClient/Extensions/UIButton+Extension.swift | 40 +++++++++++++++++++ iOSClient/Login/NCLogin.swift | 22 ++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 iOSClient/Extensions/UIButton+Extension.swift diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index ab063b2b6f..c7abccb0d6 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -67,6 +67,7 @@ F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; }; F314F1142A30E2DE00BC7FAB /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8A390295DC5E0006CB2D0 /* View+Extension.swift */; }; F321DA8A2B71205A00DDA0E6 /* NCTrashSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */; }; + F32FADA92D1176E3007035E2 /* UIButton+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */; }; F33918C42C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */; }; F33918C52C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */; }; F33918C62C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */; }; @@ -1202,6 +1203,7 @@ D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = ""; }; F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCViewerMedia+VisionKit.swift"; sourceTree = ""; }; F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrashSelectTabBar.swift; sourceTree = ""; }; + F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Extension.swift"; sourceTree = ""; }; F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileNameValidator+Extensions.swift"; sourceTree = ""; }; F33EE6F12BF4C9B200CA1A51 /* PKCS12.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS12.swift; sourceTree = ""; }; F343A4B22A1E01FF00DDA874 /* PHAsset+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PHAsset+Extension.swift"; sourceTree = ""; }; @@ -2633,6 +2635,7 @@ F7A0D14E259229FA008F8A13 /* Extensions */ = { isa = PBXGroup; children = ( + F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */, F7AC1CAF28AB94490032D99F /* Array+Extension.swift */, F7817CF729801A3500FFBC65 /* Data+Extension.swift */, AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */, @@ -4301,6 +4304,7 @@ F3CA33842D10726E00672333 /* NCLoginPollModel.swift in Sources */, F733598125C1C188002ABA72 /* NCAskAuthorization.swift in Sources */, 370D26AF248A3D7A00121797 /* NCCellProtocol.swift in Sources */, + F32FADA92D1176E3007035E2 /* UIButton+Extension.swift in Sources */, F768822C2C0DD1E7001CF441 /* NCKeychain.swift in Sources */, F7BFFD282C8846020029A201 /* NCHud.swift in Sources */, F71CD6CA2930D7B1006C95C1 /* NCApplicationHandle.swift in Sources */, @@ -5381,7 +5385,7 @@ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES; + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO; }; name = Debug; }; @@ -5404,7 +5408,7 @@ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES; + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO; }; name = Release; }; diff --git a/iOSClient/Extensions/UIButton+Extension.swift b/iOSClient/Extensions/UIButton+Extension.swift new file mode 100644 index 0000000000..70a85857a5 --- /dev/null +++ b/iOSClient/Extensions/UIButton+Extension.swift @@ -0,0 +1,40 @@ +// +// UIButton+Extension.swift +// Nextcloud +// +// Created by Milen Pivchev on 17.12.24. +// Copyright © 2024 Marino Faggiana. All rights reserved. +// + +extension UIButton { + func hideButtonAndShowSpinner(tint: UIColor = .white) { + self.isHidden = true + + let spinnerTag = Int(bitPattern: Unmanaged.passUnretained(self).toOpaque()) + if self.superview?.subviews.first(where: { view -> Bool in + return view.isKind(of: UIActivityIndicatorView.self) && view.tag == spinnerTag + }) != nil { + return + } + + let spinner = UIActivityIndicatorView(style: .medium) + spinner.tag = spinnerTag + spinner.color = tint + spinner.startAnimating() + spinner.center = self.center + self.superview?.addSubview(spinner) + spinner.translatesAutoresizingMaskIntoConstraints = false + spinner.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true + spinner.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true + } + + func hideSpinnerAndShowButton() { + let spinnerTag = Int(bitPattern: Unmanaged.passUnretained(self).toOpaque()) + let spinner = self.superview?.subviews.first(where: { view -> Bool in + return view.isKind(of: UIActivityIndicatorView.self) && view.tag == spinnerTag + }) + + spinner?.removeFromSuperview() + self.isHidden = false + } +} diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index a821b7f2eb..d43eadaced 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -324,6 +324,9 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { guard var url = baseUrlTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { return } if url.hasSuffix("/") { url = String(url.dropLast()) } if url.isEmpty { return } + + loginButton.hideButtonAndShowSpinner() + // Check whether baseUrl contain protocol. If not add https:// by default. if url.hasPrefix("https") == false && url.hasPrefix("http") == false { url = "https://" + url @@ -334,7 +337,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { func isUrlValid(url: String, user: String? = nil) { loginButton.isEnabled = false - NextcloudKit.shared.getServerStatus(serverUrl: url) { _, serverInfoResult in + NextcloudKit.shared.getServerStatus(serverUrl: url) { [self] _, serverInfoResult in switch serverInfoResult { case .success(let serverInfo): if let host = URL(string: url)?.host { @@ -350,12 +353,13 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) if useInAppBrowser { - vc = SFSafariViewController(url: url) + let safariVC = SFSafariViewController(url: url) + safariVC.delegate = self + vc = safariVC } else { vc = UIHostingController(rootView: NCLoginPoll(loginFlowV2Login: login, model: ncLoginPollModel)) } - present(vc, animated: true) } else if serverInfo.versionMajor < NCGlobal.shared.nextcloudVersion12 { // No login flow available let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: NSLocalizedString("_webflow_not_available_", comment: ""), preferredStyle: .alert) @@ -364,7 +368,9 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } } case .failure(let error): + loginButton.hideSpinnerAndShowButton() self.loginButton.isEnabled = true + if error.errorCode == NSURLErrorServerCertificateUntrusted { let alertController = UIAlertController(title: NSLocalizedString("_ssl_certificate_untrusted_", comment: ""), message: NSLocalizedString("_connect_server_anyway_", comment: ""), preferredStyle: .alert) alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", comment: ""), style: .default, handler: { _ in @@ -523,8 +529,10 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint) { [self] server, loginName, appPassword, _, error in if error == .success, let urlBase = server, let user = loginName, let appPassword { ncLoginPollModel.isLoading = true - + print("TEST: GET LOGIN FLOW") NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in + print("TEST: CREATE ACCOUNT") + if error == .success { let window = UIApplication.shared.firstWindow if let controller = window?.rootViewController as? NCMainTabBarController { @@ -558,3 +566,9 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { timer.resume() } } + +extension NCLogin: SFSafariViewControllerDelegate { + func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + loginButton.hideSpinnerAndShowButton() + } +} From 550813f17d473876a619e1c9028ac05bfc5a9583 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Tue, 17 Dec 2024 14:13:23 +0100 Subject: [PATCH 5/8] WIP Signed-off-by: Milen Pivchev --- iOSClient/Login/NCLogin.swift | 8 ++---- iOSClient/Login/Poll/NCLoginPollModel.swift | 28 --------------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index d43eadaced..d17f960d15 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -65,6 +65,8 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { var ncLoginPollModel = NCLoginPollModel() + var loginFlowInProgress = false + // MARK: - View Life Cycle override func viewDidLoad() { @@ -207,12 +209,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } } -// override func viewDidDisappear(_ animated: Bool) { -// super.viewDidDisappear(animated) -// -// pollTimer?.cancel() -// } - private func handleLoginWithAppConfig() { let accountCount = NCManageDatabase.shared.getAccounts()?.count ?? 0 diff --git a/iOSClient/Login/Poll/NCLoginPollModel.swift b/iOSClient/Login/Poll/NCLoginPollModel.swift index fe608856e7..26480fd2de 100644 --- a/iOSClient/Login/Poll/NCLoginPollModel.swift +++ b/iOSClient/Login/Poll/NCLoginPollModel.swift @@ -9,37 +9,9 @@ import Foundation class NCLoginPollModel: ObservableObject { - -// var loginFlowV2Token = "" -// var loginFlowV2Endpoint = "" - -// @Published var pollFinished = false @Published var isLoading = false -// @Published var account = "" - -// var timer: DispatchSourceTimer? - -// init(delegate: NCLoginPoll, pollFinished: Bool = false, isLoading: Bool = false, account: String = "", timer: DispatchSourceTimer? = nil) { -// self.delegate = delegate -// self.pollFinished = pollFinished -// self.isLoading = isLoading -// self.account = account -// self.timer = timer -// } - - func configure() { -// self.loginFlowV2Token = loginFlowV2Token -// self.loginFlowV2Endpoint = loginFlowV2Endpoint -// self.loginFlowV2Login = loginFlowV2Login -// -// poll() - } func openLoginInBrowser(loginFlowV2Login: String = "") { UIApplication.shared.open(URL(string: loginFlowV2Login)!) } } - -protocol NCLoginDelegate: AnyObject { - func pollDidStart() -} From 02362e320ffacbdbfdd667cf52e2451a307badcf Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Tue, 17 Dec 2024 14:21:38 +0100 Subject: [PATCH 6/8] WIP Signed-off-by: Milen Pivchev --- Nextcloud.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index c7abccb0d6..0b02bfba31 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -5385,7 +5385,7 @@ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO; + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES; }; name = Debug; }; @@ -5408,7 +5408,7 @@ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/iOSClient/Nextcloud-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; - _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO; + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES; }; name = Release; }; From 3a4e8f9145db7826fcfe3e940112d47a40b176e0 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Mon, 23 Dec 2024 16:40:14 +0100 Subject: [PATCH 7/8] Finish Signed-off-by: Milen Pivchev --- Brand/NCBrand.swift | 1 + Nextcloud.xcodeproj/project.pbxproj | 2 -- iOSClient/Login/NCLogin.swift | 20 ++++++++++---------- iOSClient/Login/Poll/NCLoginPoll.swift | 4 ---- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Brand/NCBrand.swift b/Brand/NCBrand.swift index 3fac622ea9..b30c829f98 100755 --- a/Brand/NCBrand.swift +++ b/Brand/NCBrand.swift @@ -73,6 +73,7 @@ let userAgent: String = { var doNotAskPasscodeAtStartup: Bool = false var disable_source_code_in_settings: Bool = false var enforce_passcode_lock = false + var use_in_app_browser_for_login = false // (name: "Name 1", url: "https://cloud.nextcloud.com"),(name: "Name 2", url: "https://cloud.nextcloud.com") var enforce_servers: [(name: String, url: String)] = [] diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 1f64c1e2ad..11db9f8231 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -1183,7 +1183,6 @@ AAF806B32CE25EFE009C2D43 /* NCShareToggleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareToggleCell.swift; sourceTree = ""; }; AAF806B52CE34C72009C2D43 /* NCShareDownloadLimitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareDownloadLimitViewController.swift; sourceTree = ""; }; AAF806B72CE37C15009C2D43 /* NCShareDownloadLimitTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareDownloadLimitTableViewController.swift; sourceTree = ""; }; - AAF806B92CE38BB2009C2D43 /* NextcloudKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = NextcloudKit; path = ../NextcloudKit; sourceTree = SOURCE_ROOT; }; AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Extension.swift"; sourceTree = ""; }; AF22B20B277C6F4D00DAB0CC /* NCShareCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCell.swift; sourceTree = ""; }; AF22B215277D196700DAB0CC /* NCShareExtension+DataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCShareExtension+DataSource.swift"; sourceTree = ""; }; @@ -3083,7 +3082,6 @@ F7F67B9F1A24D27800EE80DA = { isa = PBXGroup; children = ( - AAF806B92CE38BB2009C2D43 /* NextcloudKit */, F7B8B82F25681C3400967775 /* GoogleService-Info.plist */, F7C1CDD91E6DFC6F005D92BE /* Brand */, F7F67BAA1A24D27800EE80DA /* iOSClient */, diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index d17f960d15..95d4f38b63 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -59,8 +59,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { private var p12Data: Data? private var p12Password: String? - private var useInAppBrowser = true - var pollTimer: DispatchSourceTimer? var ncLoginPollModel = NCLoginPollModel() @@ -321,8 +319,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { if url.hasSuffix("/") { url = String(url.dropLast()) } if url.isEmpty { return } - loginButton.hideButtonAndShowSpinner() - // Check whether baseUrl contain protocol. If not add https:// by default. if url.hasPrefix("https") == false && url.hasPrefix("http") == false { url = "https://" + url @@ -333,6 +329,8 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { func isUrlValid(url: String, user: String? = nil) { loginButton.isEnabled = false + loginButton.hideButtonAndShowSpinner() + NextcloudKit.shared.getServerStatus(serverUrl: url) { [self] _, serverInfoResult in switch serverInfoResult { case .success(let serverInfo): @@ -340,7 +338,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { NCNetworking.shared.writeCertificate(host: host) } NextcloudKit.shared.getLoginFlowV2(serverUrl: url) { [self] token, endpoint, login, _, error in - self.loginButton.isEnabled = true // Login Flow V2 if error == .success, let token, let endpoint, let login { guard let url = URL(string: login) else { return } @@ -348,7 +345,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login) - if useInAppBrowser { + if NCBrandOptions.shared.use_in_app_browser_for_login { let safariVC = SFSafariViewController(url: url) safariVC.delegate = self vc = safariVC @@ -365,7 +362,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { } case .failure(let error): loginButton.hideSpinnerAndShowButton() - self.loginButton.isEnabled = true + loginButton.isEnabled = true if error.errorCode == NSURLErrorServerCertificateUntrusted { let alertController = UIAlertController(title: NSLocalizedString("_ssl_certificate_untrusted_", comment: ""), message: NSLocalizedString("_connect_server_anyway_", comment: ""), preferredStyle: .alert) @@ -524,10 +521,10 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint) { [self] server, loginName, appPassword, _, error in if error == .success, let urlBase = server, let user = loginName, let appPassword { + loginFlowInProgress = true ncLoginPollModel.isLoading = true - print("TEST: GET LOGIN FLOW") + NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in - print("TEST: CREATE ACCOUNT") if error == .success { let window = UIApplication.shared.firstWindow @@ -565,6 +562,9 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate { extension NCLogin: SFSafariViewControllerDelegate { func safariViewControllerDidFinish(_ controller: SFSafariViewController) { - loginButton.hideSpinnerAndShowButton() + if !loginFlowInProgress { + loginButton.isEnabled = true + loginButton.hideSpinnerAndShowButton() + } } } diff --git a/iOSClient/Login/Poll/NCLoginPoll.swift b/iOSClient/Login/Poll/NCLoginPoll.swift index dc5892aaa3..0a2638c784 100644 --- a/iOSClient/Login/Poll/NCLoginPoll.swift +++ b/iOSClient/Login/Poll/NCLoginPoll.swift @@ -25,12 +25,8 @@ import NextcloudKit import SwiftUI struct NCLoginPoll: View { - // let loginFlowV2Token: String - // let loginFlowV2Endpoint: String let loginFlowV2Login: String - // var cancelButtonDisabled = false - @ObservedObject var model: NCLoginPollModel @Environment(\.dismiss) private var dismiss From 4bee385624eb8e347bae17376c3d7f4c226da32b Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Mon, 23 Dec 2024 16:42:56 +0100 Subject: [PATCH 8/8] WIP Signed-off-by: Milen Pivchev --- Brand/NCBrand.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Brand/NCBrand.swift b/Brand/NCBrand.swift index b30c829f98..55060a521e 100755 --- a/Brand/NCBrand.swift +++ b/Brand/NCBrand.swift @@ -73,7 +73,7 @@ let userAgent: String = { var doNotAskPasscodeAtStartup: Bool = false var disable_source_code_in_settings: Bool = false var enforce_passcode_lock = false - var use_in_app_browser_for_login = false + var use_in_app_browser_for_login = true // (name: "Name 1", url: "https://cloud.nextcloud.com"),(name: "Name 2", url: "https://cloud.nextcloud.com") var enforce_servers: [(name: String, url: String)] = []