From c531b970f083ca0cedfc43400a589230d220773c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=BChne?= Date: Fri, 8 Oct 2021 11:26:22 +0200 Subject: [PATCH 1/9] add a error section with a retry button in branded login view --- .../Resources/en.lproj/Localizable.strings | 1 + .../StaticLoginSetupViewController.swift | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/ownCloud/Resources/en.lproj/Localizable.strings b/ownCloud/Resources/en.lproj/Localizable.strings index aac537d76..6d134ae94 100644 --- a/ownCloud/Resources/en.lproj/Localizable.strings +++ b/ownCloud/Resources/en.lproj/Localizable.strings @@ -70,6 +70,7 @@ "Manage Storage" = "Manage Storage"; "Access Files" = "Access Files"; "Logout" = "Logout"; +"Retry" = "Retry"; /* Bookmark Info */ "Bookmark Metadata" = "Bookmark Metadata"; diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 5f41d8531..8fb9dbbac 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -24,6 +24,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { var profile : StaticLoginProfile var bookmark : OCBookmark? var busySection : StaticTableViewSection? + var retrySection : StaticTableViewSection? private var urlString : String? private var username : String? @@ -157,17 +158,32 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { tokenMaskSection.addStaticHeader(title: profile.welcome!, message: profile.promptForTokenAuth) if VendorServices.shared.canAddAccount, OCBookmarkManager.shared.bookmarks.count > 0 { - let (proceedButton, cancelButton) = tokenMaskSection.addButtonFooter(proceedLabel: "Continue", cancelLabel: "Cancel") + let (proceedButton, cancelButton) = tokenMaskSection.addButtonFooter(proceedLabel: "Continue".localized, cancelLabel: "Cancel".localized) proceedButton?.addTarget(self, action: #selector(self.startAuthentication), for: .touchUpInside) cancelButton?.addTarget(self, action: #selector(self.cancel(_:)), for: .touchUpInside) } else { - let (proceedButton, _) = tokenMaskSection.addButtonFooter(proceedLabel: "Continue", proceedItemStyle: .welcome, cancelLabel: nil) + let (proceedButton, _) = tokenMaskSection.addButtonFooter(proceedLabel: "Continue".localized, proceedItemStyle: .welcome, cancelLabel: nil) proceedButton?.addTarget(self, action: #selector(self.startAuthentication), for: .touchUpInside) } return tokenMaskSection } + func retrySection(issues: DisplayIssues) -> StaticTableViewSection { + let retrySection : StaticTableViewSection = StaticTableViewSection(headerTitle: nil, identifier: "retrySection") + + for issue in issues.displayIssues { + if let title = issue.localizedTitle, let localizedDescription = issue.localizedDescription { + retrySection.add(row: StaticTableViewRow(message: localizedDescription, title: title)) + } + } + + let (proceedButton, _) = retrySection.addButtonFooter(proceedLabel: "Retry".localized, proceedItemStyle: .welcome, cancelLabel: nil) + proceedButton?.addTarget(self, action: #selector(proceedWithLogin), for: .touchUpInside) + + return retrySection + } + func busySection(message: String) -> StaticTableViewSection { let busySection : StaticTableViewSection = StaticTableViewSection(headerTitle: nil, identifier: "busySection") let activityIndicator : UIActivityIndicatorView = UIActivityIndicatorView(style: Theme.shared.activeCollection.activityIndicatorViewStyle) @@ -285,7 +301,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { } } - func proceedWithLogin() { + @objc func proceedWithLogin() { guard self.bookmark != nil else { let alertController = ThemedAlertController(title: "Missing Profile URL".localized, message: String(format: "The Profile '%@' does not have a URL configured.\nPlease provide a URL via configuration or MDM.".localized, profile.name ?? ""), preferredStyle: .alert) @@ -301,6 +317,9 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if let onboardingSection = self.sectionForIdentifier("onboardingSection") { self.removeSection(onboardingSection) } + if let retrySection = self.sectionForIdentifier("retrySection") { + self.removeSection(retrySection) + } if busySection == nil { busySection = self.busySection(message: "Contacting server…".localized) @@ -541,6 +560,10 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if let busySection = self.busySection, busySection.attached { self.removeSection(busySection) } + self.retrySection = self.retrySection(issues: displayIssues) + if let retrySection = self.retrySection { + self.addSection(retrySection) + } IssuesCardViewController.present(on: loginViewController, issue: issue, displayIssues: displayIssues, completion: { [weak issue] (response) in switch response { From 22d11a3a3d038c2dc7084c1ec9a5af33479d58e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=BChne?= Date: Tue, 19 Oct 2021 15:25:40 +0200 Subject: [PATCH 2/9] #4786 added a retry interval of 10 seconds. In this time interval the app retries to establish the connection before a error message will be shown --- .../StaticLoginSetupViewController.swift | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 8fb9dbbac..c02997872 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -31,6 +31,8 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { private var password : String? private var passwordRow : StaticTableViewRow? private var isAuthenticating = false + private var retryTimeout : Date? + private var retryInterval : TimeInterval = 10 init(loginViewController theLoginViewController: StaticLoginViewController, profile theProfile: StaticLoginProfile) { profile = theProfile @@ -460,27 +462,37 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { var proceed : Bool = true if let issue = connectionIssue { - proceed = self.show(issue: issue, proceed: { () in + if self.retryTimeout == nil { + self.retryTimeout = Date().addingTimeInterval(self.retryInterval) + } + if let retryDate = self.retryTimeout, Date() < retryDate { + proceed = false OnMainThread { - if isInitialRequest { - self.determineSupportedAuthMethod(false) - } + self.determineSupportedAuthMethod(false) } - }, cancel: { () in - OnMainThread { - if self.profile.canConfigureURL { - if let busySection = self.busySection, busySection.attached { - self.removeSection(busySection) + } else { + proceed = self.show(issue: issue, proceed: { () in + OnMainThread { + if isInitialRequest { + self.determineSupportedAuthMethod(false) } - self.addSection(self.urlSection()) - if OCBookmarkManager.shared.bookmarks.count == 0, self.profile.isOnboardingEnabled, self.sectionForIdentifier("onboardingSection") == nil { - self.addSection(self.onboardingSection()) + } + }, cancel: { () in + OnMainThread { + if self.profile.canConfigureURL { + if let busySection = self.busySection, busySection.attached { + self.removeSection(busySection) + } + self.addSection(self.urlSection()) + if OCBookmarkManager.shared.bookmarks.count == 0, self.profile.isOnboardingEnabled, self.sectionForIdentifier("onboardingSection") == nil { + self.addSection(self.onboardingSection()) + } + } else { + self.cancel(nil) } - } else { - self.cancel(nil) } - } - }) + }) + } } if proceed { From 814ac534c18f126a501c4276b0e3a5e61fb294a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=BChne?= Date: Wed, 20 Oct 2021 09:41:29 +0200 Subject: [PATCH 3/9] only retry for network issues --- .../Static Login/Interface/StaticLoginSetupViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index c02997872..9921ed394 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -465,7 +465,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if self.retryTimeout == nil { self.retryTimeout = Date().addingTimeInterval(self.retryInterval) } - if let retryDate = self.retryTimeout, Date() < retryDate { + if let retryDate = self.retryTimeout, Date() < retryDate, issue.error?.isNetworkConnectionError == true { proceed = false OnMainThread { self.determineSupportedAuthMethod(false) From d5a78649ffcdb686986a908b0e4b07b743fd80c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=BChne?= Date: Wed, 20 Oct 2021 10:34:20 +0200 Subject: [PATCH 4/9] only show retry section on network issues --- .../Static Login/Interface/StaticLoginSetupViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 9921ed394..26694b421 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -573,7 +573,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { self.removeSection(busySection) } self.retrySection = self.retrySection(issues: displayIssues) - if let retrySection = self.retrySection { + if let retrySection = self.retrySection, issue.error?.isNetworkConnectionError == true { self.addSection(retrySection) } From 6aa31732f91adc20e06fbc49721eba3f95e48d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Hu=CC=88hne?= Date: Mon, 25 Oct 2021 15:21:05 +0200 Subject: [PATCH 5/9] - changed retry time interval to 30 seconds - retries minimum of 3 times --- .../StaticLoginSetupViewController.swift | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 26694b421..86881e35e 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -32,7 +32,10 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { private var passwordRow : StaticTableViewRow? private var isAuthenticating = false private var retryTimeout : Date? - private var retryInterval : TimeInterval = 10 + private let retryInterval : TimeInterval = 30 + private var retries : Int = 0 + private let numberOfRetries : Int = 3 + private let busySectionMessageLabel : UILabel = UILabel() init(loginViewController theLoginViewController: StaticLoginViewController, profile theProfile: StaticLoginProfile) { profile = theProfile @@ -191,23 +194,22 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { let activityIndicator : UIActivityIndicatorView = UIActivityIndicatorView(style: Theme.shared.activeCollection.activityIndicatorViewStyle) let containerView : FullWidthHeaderView = FullWidthHeaderView() let centerView : UIView = UIView() - let messageLabel : UILabel = UILabel() containerView.translatesAutoresizingMaskIntoConstraints = false centerView.translatesAutoresizingMaskIntoConstraints = false - messageLabel.translatesAutoresizingMaskIntoConstraints = false + busySectionMessageLabel.translatesAutoresizingMaskIntoConstraints = false activityIndicator.translatesAutoresizingMaskIntoConstraints = false centerView.addSubview(activityIndicator) - centerView.addSubview(messageLabel) + centerView.addSubview(busySectionMessageLabel) containerView.addSubview(centerView) containerView.addThemeApplier({ (_, collection, _) in - messageLabel.applyThemeCollection(collection, itemStyle: .welcomeMessage) + self.busySectionMessageLabel.applyThemeCollection(collection, itemStyle: .welcomeMessage) }) - messageLabel.text = message + busySectionMessageLabel.text = message NSLayoutConstraint.activate([ activityIndicator.widthAnchor.constraint(equalToConstant: 30), @@ -216,9 +218,9 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { activityIndicator.topAnchor.constraint(equalTo: centerView.topAnchor), activityIndicator.bottomAnchor.constraint(equalTo: centerView.bottomAnchor), - messageLabel.centerYAnchor.constraint(equalTo: centerView.centerYAnchor), - messageLabel.leftAnchor.constraint(equalTo: activityIndicator.rightAnchor, constant: 20), - messageLabel.rightAnchor.constraint(equalTo: centerView.rightAnchor), + busySectionMessageLabel.centerYAnchor.constraint(equalTo: centerView.centerYAnchor), + busySectionMessageLabel.leftAnchor.constraint(equalTo: activityIndicator.rightAnchor, constant: 20), + busySectionMessageLabel.rightAnchor.constraint(equalTo: centerView.rightAnchor), centerView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 40), centerView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor), @@ -465,9 +467,11 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if self.retryTimeout == nil { self.retryTimeout = Date().addingTimeInterval(self.retryInterval) } - if let retryDate = self.retryTimeout, Date() < retryDate, issue.error?.isNetworkConnectionError == true { + if let retryDate = self.retryTimeout, self.retries <= self.numberOfRetries, Date() < retryDate, issue.error?.isNetworkConnectionError == true { + self.retries += 1 proceed = false OnMainThread { + self.busySectionMessageLabel.text = String(format: "%@ (%ld)", "Contacting server…".localized, self.retries) self.determineSupportedAuthMethod(false) } } else { From 6a0190281a4287454d6c54470a26412c45fc8ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=BChne?= Date: Mon, 25 Oct 2021 15:43:35 +0200 Subject: [PATCH 6/9] Update ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift Co-authored-by: Felix Schwarz --- .../Static Login/Interface/StaticLoginSetupViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 86881e35e..f2ba7a70d 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -467,7 +467,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if self.retryTimeout == nil { self.retryTimeout = Date().addingTimeInterval(self.retryInterval) } - if let retryDate = self.retryTimeout, self.retries <= self.numberOfRetries, Date() < retryDate, issue.error?.isNetworkConnectionError == true { + if let retryDate = self.retryTimeout, ((Date() < retryDate) || self.retries <= self.numberOfRetries), issue.error?.isNetworkConnectionError == true { self.retries += 1 proceed = false OnMainThread { From d3adbb2578f381a31f29e4c32e3ad51de6560a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Hu=CC=88hne?= Date: Tue, 26 Oct 2021 15:07:58 +0200 Subject: [PATCH 7/9] fixed connection retry and show retry section UI --- .../Interface/StaticLoginSetupViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index f2ba7a70d..4c166c1cc 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -467,7 +467,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { if self.retryTimeout == nil { self.retryTimeout = Date().addingTimeInterval(self.retryInterval) } - if let retryDate = self.retryTimeout, ((Date() < retryDate) || self.retries <= self.numberOfRetries), issue.error?.isNetworkConnectionError == true { + if let retryDate = self.retryTimeout, ((Date() < retryDate) || self.retries <= self.numberOfRetries), issue.issues?.first?.error?.isNetworkConnectionError == true { self.retries += 1 proceed = false OnMainThread { @@ -577,7 +577,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { self.removeSection(busySection) } self.retrySection = self.retrySection(issues: displayIssues) - if let retrySection = self.retrySection, issue.error?.isNetworkConnectionError == true { + if let retrySection = self.retrySection, issue.issues?.first?.error?.isNetworkConnectionError == true { self.addSection(retrySection) } From 414eb33e26d8d11cbb439a3b2a55123657ea1f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Hu=CC=88hne?= Date: Wed, 27 Oct 2021 10:17:10 +0200 Subject: [PATCH 8/9] HTTP pipeline is ready to schedule HTTP requests before the Static Login View Controller is brought up. Moved it before setting up the UIWindow --- ownCloud/AppDelegate.swift | 5 +++-- ownCloud/SceneDelegate.swift | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ownCloud/AppDelegate.swift b/ownCloud/AppDelegate.swift index f3bd4f29b..0d0d72329 100644 --- a/ownCloud/AppDelegate.swift +++ b/ownCloud/AppDelegate.swift @@ -44,6 +44,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Set up license management OCLicenseManager.shared.setupLicenseManagement() + // Set up HTTP pipelines + OCHTTPPipelineManager.setupPersistentPipelines() + // Set up app window = ThemeWindow(frame: UIScreen.main.bounds) @@ -75,8 +78,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { AppLockManager.shared.showLockscreenIfNeeded() } - OCHTTPPipelineManager.setupPersistentPipelines() // Set up HTTP pipelines - FileProviderInterfaceManager.shared.updateDomainsFromBookmarks() ScheduledTaskManager.shared.setup() diff --git a/ownCloud/SceneDelegate.swift b/ownCloud/SceneDelegate.swift index a2bcb6750..c6c861a67 100644 --- a/ownCloud/SceneDelegate.swift +++ b/ownCloud/SceneDelegate.swift @@ -26,6 +26,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // UIWindowScene delegate func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Set up HTTP pipelines + OCHTTPPipelineManager.setupPersistentPipelines() + if let windowScene = scene as? UIWindowScene { window = ThemeWindow(windowScene: windowScene) var navigationController: UINavigationController? From 119f8afee0e8a0eea703b636e3bac2e29b45df99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Hu=CC=88hne?= Date: Thu, 28 Oct 2021 11:15:14 +0200 Subject: [PATCH 9/9] removed connection retries output and put it into the log --- .../Static Login/Interface/StaticLoginSetupViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift index 4c166c1cc..b04e07e56 100644 --- a/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift +++ b/ownCloud/Static Login/Interface/StaticLoginSetupViewController.swift @@ -471,7 +471,7 @@ class StaticLoginSetupViewController : StaticLoginStepViewController { self.retries += 1 proceed = false OnMainThread { - self.busySectionMessageLabel.text = String(format: "%@ (%ld)", "Contacting server…".localized, self.retries) + Log.warning(String(format: "%@ (%ld)", "Contacting server…".localized, self.retries)) self.determineSupportedAuthMethod(false) } } else {