diff options
Diffstat (limited to 'ios')
35 files changed, 67 insertions, 545 deletions
diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index 695bf14a17..73eca63dda 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -45,6 +45,9 @@ with the option to buy more time. - Fix invalid map camera position during the app launch and keep it up to date when multitasking. - Fix animation glitch when expanding partially visible cell in location picker. +## Removed +- Remove iOS 12 support. + ## [2022.2] - 2022-04-28 ### Added diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 35842fcd3a..e86d8aab37 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -53,11 +53,9 @@ 5820675E26E6839900655B05 /* PresentAlertOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820675D26E6839900655B05 /* PresentAlertOperation.swift */; }; 5820676226E75D8500655B05 /* REST.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820674D26E6510200655B05 /* REST.swift */; }; 5820676426E771DB00655B05 /* TunnelManagerErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820676326E771DB00655B05 /* TunnelManagerErrors.swift */; }; - 5820676826E79E7B00655B05 /* Result+UIBackgroundFetchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820676726E79E7B00655B05 /* Result+UIBackgroundFetchResult.swift */; }; 5820EDA9288FE064006BF4E4 /* DeviceManagementInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820EDA8288FE064006BF4E4 /* DeviceManagementInteractor.swift */; }; 5820EDAB288FF0D2006BF4E4 /* DeviceRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820EDAA288FF0D2006BF4E4 /* DeviceRowView.swift */; }; 5823FA5426CE49F700283BF8 /* TunnelObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5823FA5326CE49F600283BF8 /* TunnelObserver.swift */; }; - 58289082286B590900478596 /* UIFont+Monospaced.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58289081286B590900478596 /* UIFont+Monospaced.swift */; }; 58293FAE2510CA58005D0BB5 /* ProblemReportViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FAC2510CA58005D0BB5 /* ProblemReportViewController.swift */; }; 58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FB025124117005D0BB5 /* CustomTextField.swift */; }; 58293FB3251241B4005D0BB5 /* CustomTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FB2251241B3005D0BB5 /* CustomTextView.swift */; }; @@ -119,7 +117,6 @@ 58554F7D280D6FE000013055 /* RESTURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58554F7C280D6FE000013055 /* RESTURLSession.swift */; }; 58561C99239A5D1500BD6B5E /* IPEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58561C98239A5D1500BD6B5E /* IPEndpoint.swift */; }; 58561C9A239A5D1500BD6B5E /* IPEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58561C98239A5D1500BD6B5E /* IPEndpoint.swift */; }; - 5856D13727450A8A00DFD627 /* UIImage+TintColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5856D13627450A8A00DFD627 /* UIImage+TintColor.swift */; }; 5857F23424C8443700CF6F47 /* AsyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E973DD24850EB600096F90 /* AsyncOperation.swift */; }; 5857F23824C8446700CF6F47 /* AsyncBlockOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */; }; 5857F24324C8662600CF6F47 /* SelectLocationHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */; }; @@ -401,7 +398,6 @@ 5820675A26E6576800655B05 /* RelayCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayCache.swift; sourceTree = "<group>"; }; 5820675D26E6839900655B05 /* PresentAlertOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresentAlertOperation.swift; sourceTree = "<group>"; }; 5820676326E771DB00655B05 /* TunnelManagerErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelManagerErrors.swift; sourceTree = "<group>"; }; - 5820676726E79E7B00655B05 /* Result+UIBackgroundFetchResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Result+UIBackgroundFetchResult.swift"; sourceTree = "<group>"; }; 5820EDA8288FE064006BF4E4 /* DeviceManagementInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceManagementInteractor.swift; sourceTree = "<group>"; }; 5820EDAA288FF0D2006BF4E4 /* DeviceRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRowView.swift; sourceTree = "<group>"; }; 58218E1428B65058000C624F /* IPv4Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPv4Header.h; sourceTree = "<group>"; }; @@ -409,7 +405,6 @@ 58218E1628B65396000C624F /* ICMPHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ICMPHeader.h; sourceTree = "<group>"; }; 5823FA4F26CA690600283BF8 /* OSLogHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSLogHandler.swift; sourceTree = "<group>"; }; 5823FA5326CE49F600283BF8 /* TunnelObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelObserver.swift; sourceTree = "<group>"; }; - 58289081286B590900478596 /* UIFont+Monospaced.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Monospaced.swift"; sourceTree = "<group>"; }; 58293FAC2510CA58005D0BB5 /* ProblemReportViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProblemReportViewController.swift; sourceTree = "<group>"; }; 58293FB025124117005D0BB5 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; }; 58293FB2251241B3005D0BB5 /* CustomTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextView.swift; sourceTree = "<group>"; }; @@ -452,7 +447,6 @@ 58554F7A280B125F00013055 /* RESTAccountsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTAccountsProxy.swift; sourceTree = "<group>"; }; 58554F7C280D6FE000013055 /* RESTURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTURLSession.swift; sourceTree = "<group>"; }; 58561C98239A5D1500BD6B5E /* IPEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPEndpoint.swift; sourceTree = "<group>"; }; - 5856D13627450A8A00DFD627 /* UIImage+TintColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+TintColor.swift"; sourceTree = "<group>"; }; 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationHeaderView.swift; sourceTree = "<group>"; }; 5857F24624C882D700CF6F47 /* SelectLocationNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationNavigationController.swift; sourceTree = "<group>"; }; 585CA70E25F8C44600B47C62 /* UIMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIMetrics.swift; sourceTree = "<group>"; }; @@ -965,7 +959,6 @@ 58781CD422AFBA39009B9D8E /* RelaySelector.swift */, 585DA87F26B0268500B8C587 /* REST */, 58F1311427E0B2AB007AC5BC /* Result+Extensions.swift */, - 5820676726E79E7B00655B05 /* Result+UIBackgroundFetchResult.swift */, 580909D22876D09A0078138D /* RevokedDeviceViewController.swift */, 587425C02299833500CA2045 /* RootContainerViewController.swift */, 58E25F802837BBBB002CFB2C /* SceneDelegate.swift */, @@ -1005,8 +998,6 @@ 5891BF5025E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift */, 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */, 58CCA0152242560B004F3011 /* UIColor+Palette.swift */, - 58289081286B590900478596 /* UIFont+Monospaced.swift */, - 5856D13627450A8A00DFD627 /* UIImage+TintColor.swift */, 585CA70E25F8C44600B47C62 /* UIMetrics.swift */, 58F7CA872692E34000FC59FD /* WireguardKeysContentView.swift */, 58E511E028DDB7F100B0BCDE /* WrappingError.swift */, @@ -1377,7 +1368,6 @@ 58A1AA8C23F5584C009F7EA6 /* ConnectionPanelView.swift in Sources */, 582BB1B3229574F40055B6EF /* SettingsAccountCell.swift in Sources */, 588527B2276B3F0700BAA373 /* LoadTunnelConfigurationOperation.swift in Sources */, - 58289082286B590900478596 /* UIFont+Monospaced.swift in Sources */, 58F1311527E0B2AB007AC5BC /* Result+Extensions.swift in Sources */, 5872631B283F6EAB00E14ADF /* Intents.intentdefinition in Sources */, 585DA88426B0270700B8C587 /* ServerRelaysResponse.swift in Sources */, @@ -1416,7 +1406,6 @@ 58F2E146276A2C9900A79513 /* StopTunnelOperation.swift in Sources */, E1187ABC289BBB850024E748 /* OutOfTimeViewController.swift in Sources */, 58DF5B762852108E00E92647 /* InputInjectionBuilder.swift in Sources */, - 5856D13727450A8A00DFD627 /* UIImage+TintColor.swift in Sources */, 58CB0EE024B86751001EF0D8 /* RESTAPIProxy.swift in Sources */, 58095C532760EEC700890776 /* RESTNetworkOperation.swift in Sources */, 58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */, @@ -1480,7 +1469,6 @@ 585DA89326B0323E00B8C587 /* TunnelProviderMessage.swift in Sources */, 5891BF1C25E3E3EB006D6FB0 /* Bundle+ProductVersion.swift in Sources */, 588BCF26280FE79A009ADCEC /* RESTProxy.swift in Sources */, - 5820676826E79E7B00655B05 /* Result+UIBackgroundFetchResult.swift in Sources */, 5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */, 58CE5E66224146200008646E /* LoginViewController.swift in Sources */, 58EF580B25D69D7A00AEBA94 /* ProblemReportSubmissionOverlayView.swift in Sources */, @@ -1737,7 +1725,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1794,7 +1782,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; diff --git a/ios/MullvadVPN/AccountContentView.swift b/ios/MullvadVPN/AccountContentView.swift index b0ff256dbc..13c78226e7 100644 --- a/ios/MullvadVPN/AccountContentView.swift +++ b/ios/MullvadVPN/AccountContentView.swift @@ -197,7 +197,7 @@ class AccountNumberRow: UIView { private let accountNumberLabel: UILabel = { let textLabel = UILabel() textLabel.translatesAutoresizingMaskIntoConstraints = false - textLabel.font = UIFont.backport_monospacedSystemFont(ofSize: 17, weight: .regular) + textLabel.font = UIFont.monospacedSystemFont(ofSize: 17, weight: .regular) textLabel.textColor = .white return textLabel }() @@ -323,12 +323,10 @@ class AccountNumberRow: UIView { ) ) } else { - var attributes: [NSAttributedString.Key: Any]? - if #available(iOS 13.0, *) { - attributes = [.accessibilitySpeechSpellOut: true] - } - - return NSAttributedString(string: accountNumber, attributes: attributes) + return NSAttributedString( + string: accountNumber, + attributes: [.accessibilitySpeechSpellOut: true] + ) } } diff --git a/ios/MullvadVPN/AccountInputGroupView.swift b/ios/MullvadVPN/AccountInputGroupView.swift index 39ece2f367..3644069c6c 100644 --- a/ios/MullvadVPN/AccountInputGroupView.swift +++ b/ios/MullvadVPN/AccountInputGroupView.swift @@ -330,14 +330,9 @@ class AccountInputGroupView: UIView { if let accountNumber = accountNumber { let formattedNumber = StringFormatter.formattedAccountNumber(from: accountNumber) - var attributes: [NSAttributedString.Key: Any]? - if #available(iOS 13.0, *) { - attributes = [.accessibilitySpeechSpellOut: true] - } - lastUsedAccountButton.accessibilityAttributedValue = NSAttributedString( string: accountNumber, - attributes: attributes + attributes: [.accessibilitySpeechSpellOut: true] ) UIView.performWithoutAnimation { @@ -411,7 +406,7 @@ class AccountInputGroupView: UIView { // MARK: - Private private static func accountNumberFont() -> UIFont { - return UIFont.backport_monospacedSystemFont(ofSize: 20, weight: .regular) + return UIFont.monospacedSystemFont(ofSize: 20, weight: .regular) } private func addTextFieldNotificationObservers() { diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift index 5719328c27..88b8654fc8 100644 --- a/ios/MullvadVPN/AccountViewController.swift +++ b/ios/MullvadVPN/AccountViewController.swift @@ -151,9 +151,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb contentView.logoutButton.isEnabled = isInteractionEnabled view.isUserInteractionEnabled = isInteractionEnabled - if #available(iOS 13.0, *) { - isModalInPresentation = !isInteractionEnabled - } + isModalInPresentation = !isInteractionEnabled + navigationItem.setHidesBackButton(!isInteractionEnabled, animated: animated) } diff --git a/ios/MullvadVPN/AppButton.swift b/ios/MullvadVPN/AppButton.swift index 7704fbe49f..7aa404b7f4 100644 --- a/ios/MullvadVPN/AppButton.swift +++ b/ios/MullvadVPN/AppButton.swift @@ -287,21 +287,6 @@ class CustomButton: UIButton { } } - override func layoutSubviews() { - super.layoutSubviews() - - if #available(iOS 13, *) { - // no-op - } else { - // Fix: on iOS 12 the image view frame is not always set, even though the `UIButton` - // calls `imageRect` to compute the image layout frame. - let imageRect = imageRect(forContentRect: contentRect(forBounds: bounds)) - if imageView?.frame != imageRect { - imageView?.frame = imageRect - } - } - } - private func computeLayout(forContentRect contentRect: CGRect) -> (CGRect, CGRect) { var imageRect = super.imageRect(forContentRect: contentRect) var titleRect = super.titleRect(forContentRect: contentRect) diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index 10d44fd99b..66a99cc302 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -27,9 +27,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return operationQueue }() - // An instance of scene delegate used on iOS 12 or earlier. - private var sceneDelegate: SceneDelegate? - // MARK: - Application lifecycle func application( @@ -45,14 +42,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { SimulatorTunnelProvider.shared.delegate = simulatorTunnelProvider #endif - if #available(iOS 13.0, *) { - registerBackgroundTasks() - } else { - application.setMinimumBackgroundFetchInterval( - ApplicationConfiguration.minimumBackgroundFetchInterval - ) - } - + registerBackgroundTasks() setupPaymentHandler() setupNotificationHandler() @@ -74,13 +64,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { operationQueue.addOperation(setupTunnelManagerOperation) - if #available(iOS 13, *) { - // no-op - } else { - sceneDelegate = SceneDelegate() - sceneDelegate?.setupScene(windowFactory: ClassicWindowFactory()) - } - return true } @@ -97,97 +80,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - func application( - _ application: UIApplication, - performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) - -> Void - ) { - logger.debug("Start background refresh.") - - let updateAddressCacheOperation = ResultBlockOperation<Bool, Error> { operation in - let handle = AddressCache.Tracker.shared.updateEndpoints { completion in - operation.finish(completion: completion) - } - - operation.addCancellationBlock { - handle.cancel() - } - } - - let updateRelaysOperation = ResultBlockOperation<RelayCache.FetchResult, Error> - { operation in - let handle = RelayCache.Tracker.shared.updateRelays { completion in - operation.finish(completion: completion) - } - - operation.addCancellationBlock { - handle.cancel() - } - } - - let rotatePrivateKeyOperation = ResultBlockOperation<Bool, Error> { operation in - let handle = TunnelManager.shared.rotatePrivateKey(forceRotate: false) { completion in - operation.finish(completion: completion) - } - - operation.addCancellationBlock { - handle.cancel() - } - } - rotatePrivateKeyOperation.addDependencies([ - updateRelaysOperation, - updateAddressCacheOperation, - ]) - - let operations = [ - updateAddressCacheOperation, - updateRelaysOperation, - rotatePrivateKeyOperation, - ] - - let completeOperation = TransformOperation<UIBackgroundFetchResult, Void, Never>( - dispatchQueue: .main - ) - - completeOperation.setExecutionBlock { backgroundFetchResult in - self.logger.debug("Finish background refresh. Status: \(backgroundFetchResult).") - - completionHandler(backgroundFetchResult) - } - - completeOperation.injectMany(context: [UIBackgroundFetchResult]()) - .injectCompletion(from: updateAddressCacheOperation, via: { results, completion in - results.append(completion.backgroundFetchResult { $0 }) - }) - .injectCompletion(from: updateRelaysOperation, via: { results, completion in - results.append(completion.backgroundFetchResult { $0 == .newContent }) - }) - .injectCompletion(from: rotatePrivateKeyOperation, via: { results, completion in - results.append(completion.backgroundFetchResult { $0 }) - }) - .reduce { operationResults in - let initialResult = operationResults.first ?? .failed - let backgroundFetchResult = operationResults - .reduce(initialResult) { partialResult, other in - return partialResult.combine(with: other) - } - - return backgroundFetchResult - } - - let groupOperation = GroupOperation(operations: operations) - groupOperation.addObserver( - BackgroundObserver(name: "Background refresh", cancelUponExpiration: true) - ) - - let operationQueue = AsyncOperationQueue() - operationQueue.addOperation(groupOperation) - operationQueue.addOperation(completeOperation) - } - // MARK: - UISceneSession lifecycle - @available(iOS 13.0, *) func application( _ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, @@ -204,7 +98,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return sceneConfiguration } - @available(iOS 13.0, *) func application( _ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession> @@ -216,14 +109,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // MARK: - Background tasks - @available(iOS 13, *) private func registerBackgroundTasks() { registerAppRefreshTask() registerAddressCacheUpdateTask() registerKeyRotationTask() } - @available(iOS 13.0, *) private func registerAppRefreshTask() { let isRegistered = BGTaskScheduler.shared.register( forTaskWithIdentifier: ApplicationConfiguration.appRefreshTaskIdentifier, @@ -247,7 +138,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - @available(iOS 13.0, *) private func registerKeyRotationTask() { let isRegistered = BGTaskScheduler.shared.register( forTaskWithIdentifier: ApplicationConfiguration.privateKeyRotationTaskIdentifier, @@ -271,7 +161,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - @available(iOS 13.0, *) private func registerAddressCacheUpdateTask() { let isRegistered = BGTaskScheduler.shared.register( forTaskWithIdentifier: ApplicationConfiguration.addressCacheUpdateTaskIdentifier, @@ -295,14 +184,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - @available(iOS 13.0, *) func scheduleBackgroundTasks() { scheduleAppRefreshTask() scheduleKeyRotationTask() scheduleAddressCacheUpdateTask() } - @available(iOS 13.0, *) private func scheduleAppRefreshTask() { do { let date = RelayCache.Tracker.shared.getNextUpdateDate() @@ -323,7 +210,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - @available(iOS 13.0, *) private func scheduleKeyRotationTask() { do { guard let date = TunnelManager.shared.getNextKeyRotationDate() else { @@ -347,7 +233,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - @available(iOS 13.0, *) private func scheduleAddressCacheUpdateTask() { do { let date = AddressCache.Tracker.shared.nextScheduleDate() @@ -411,14 +296,10 @@ extension AppDelegate: UNUserNotificationCenterDelegate { if response.notification.request.identifier == accountExpiryNotificationIdentifier, response.actionIdentifier == UNNotificationDefaultActionIdentifier { - if #available(iOS 13.0, *) { - let sceneDelegate = UIApplication.shared.connectedScenes - .first?.delegate as? SceneDelegate + let sceneDelegate = UIApplication.shared.connectedScenes + .first?.delegate as? SceneDelegate - sceneDelegate?.showUserAccount() - } else { - self.sceneDelegate?.showUserAccount() - } + sceneDelegate?.showUserAccount() } completionHandler() diff --git a/ios/MullvadVPN/AutomaticKeyboardResponder.swift b/ios/MullvadVPN/AutomaticKeyboardResponder.swift index ee3a97bfa8..553b9d948a 100644 --- a/ios/MullvadVPN/AutomaticKeyboardResponder.swift +++ b/ios/MullvadVPN/AutomaticKeyboardResponder.swift @@ -171,10 +171,12 @@ extension AutomaticKeyboardResponder { self.init(targetView: targetView) { scrollView, offset in if scrollView.canBecomeFirstResponder { scrollView.contentInset.bottom = targetView.isFirstResponder ? offset : 0 - scrollView.scrollIndicatorInsets.bottom = targetView.isFirstResponder ? offset : 0 + scrollView.verticalScrollIndicatorInsets.bottom = targetView.isFirstResponder + ? offset + : 0 } else { scrollView.contentInset.bottom = offset - scrollView.scrollIndicatorInsets.bottom = offset + scrollView.verticalScrollIndicatorInsets.bottom = offset } } } diff --git a/ios/MullvadVPN/ConnectContentView.swift b/ios/MullvadVPN/ConnectContentView.swift index f158aa90eb..faa54413b7 100644 --- a/ios/MullvadVPN/ConnectContentView.swift +++ b/ios/MullvadVPN/ConnectContentView.swift @@ -108,10 +108,7 @@ class ConnectContentView: UIView { backgroundColor = .primaryColor layoutMargins = UIMetrics.contentLayoutMargins - - if #available(iOS 13.0, *) { - accessibilityContainerType = .semanticGroup - } + accessibilityContainerType = .semanticGroup addSubviews() } diff --git a/ios/MullvadVPN/ConnectViewController.swift b/ios/MullvadVPN/ConnectViewController.swift index e3da0fe159..078edaf8f0 100644 --- a/ios/MullvadVPN/ConnectViewController.swift +++ b/ios/MullvadVPN/ConnectViewController.swift @@ -501,10 +501,8 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen forAnnotationViewWithReuseIdentifier: Self.locationMarkerReuseIdentifier ) - if #available(iOS 13.0, *) { - // Use dark style for the map to dim the map grid - contentView.mapView.overrideUserInterfaceStyle = .dark - } + // Use dark style for the map to dim the map grid + contentView.mapView.overrideUserInterfaceStyle = .dark addTileOverlay() loadGeoJSONData() diff --git a/ios/MullvadVPN/CustomNavigationBar.swift b/ios/MullvadVPN/CustomNavigationBar.swift index 5d56f92e5b..f326dd57da 100644 --- a/ios/MullvadVPN/CustomNavigationBar.swift +++ b/ios/MullvadVPN/CustomNavigationBar.swift @@ -18,28 +18,12 @@ class CustomNavigationBar: UINavigationBar { .foregroundColor: UIColor.NavigationBar.backButtonTitleColor, ] - private static let setupAppearanceForIOS12Once: Void = { - if #available(iOS 13, *) { - // no-op - } else { - let buttonAppearance = UIBarButtonItem - .appearance(whenContainedInInstancesOf: [CustomNavigationBar.self]) - buttonAppearance.setBackButtonTitlePositionAdjustment( - CustomNavigationBar.backButtonTitlePositionOffset, - for: .default - ) - buttonAppearance.setTitleTextAttributes( - CustomNavigationBar.titleTextAttributes, - for: .normal - ) - } - }() - private let customBackIndicatorImage = UIImage(named: "IconBack")? - .backport_withTintColor( + .withTintColor( UIColor.NavigationBar.backButtonIndicatorColor, renderingMode: .alwaysOriginal ) + private let customBackIndicatorTransitionMask = UIImage(named: "IconBackTransitionMask") // Returns the distance from the title label to the bottom of navigation bar @@ -62,8 +46,6 @@ class CustomNavigationBar: UINavigationBar { } override init(frame: CGRect) { - Self.setupAppearanceForIOS12Once - super.init(frame: frame) var margins = layoutMargins @@ -83,21 +65,10 @@ class CustomNavigationBar: UINavigationBar { backgroundColor = UIColor.NavigationBar.backgroundColor isTranslucent = false - if #available(iOS 13, *) { - standardAppearance = makeNavigationBarAppearance() - scrollEdgeAppearance = makeNavigationBarAppearance() - } else { - backIndicatorImage = customBackIndicatorImage - backIndicatorTransitionMaskImage = customBackIndicatorTransitionMask - barTintColor = UIColor.NavigationBar.backgroundColor - - titleTextAttributes = Self.titleTextAttributes - largeTitleTextAttributes = Self.titleTextAttributes - shadowImage = UIImage() - } + standardAppearance = makeNavigationBarAppearance() + scrollEdgeAppearance = makeNavigationBarAppearance() } - @available(iOS 13, *) private func makeNavigationBarAppearance() -> UINavigationBarAppearance { let navigationBarAppearance = UINavigationBarAppearance() navigationBarAppearance.configureWithTransparentBackground() diff --git a/ios/MullvadVPN/CustomSplitViewController.swift b/ios/MullvadVPN/CustomSplitViewController.swift index 752eae49e9..a73441bd46 100644 --- a/ios/MullvadVPN/CustomSplitViewController.swift +++ b/ios/MullvadVPN/CustomSplitViewController.swift @@ -32,24 +32,11 @@ class CustomSplitViewController: UISplitViewController, RootContainment { } override var childForStatusBarStyle: UIViewController? { - if #available(iOS 13, *) { - return super.childForStatusBarStyle - } else { - return viewControllers.last - } + super.childForStatusBarStyle } override var childForStatusBarHidden: UIViewController? { - if #available(iOS 13, *) { - return super.childForStatusBarHidden - } else { - return viewControllers.last - } - } - - override var shouldAutomaticallyForwardAppearanceMethods: Bool { - // iOS 12: force split view controller to forward appearance events. - return true + super.childForStatusBarHidden } override func viewDidLayoutSubviews() { diff --git a/ios/MullvadVPN/CustomSwitch.swift b/ios/MullvadVPN/CustomSwitch.swift index fb3d5bc3eb..0172441489 100644 --- a/ios/MullvadVPN/CustomSwitch.swift +++ b/ios/MullvadVPN/CustomSwitch.swift @@ -29,10 +29,7 @@ class CustomSwitch: UISwitch { tintColor = .clear onTintColor = .clear - - if #available(iOS 13.0, *) { - overrideUserInterfaceStyle = .light - } + overrideUserInterfaceStyle = .light updateThumbColor(isOn: isOn, animated: false) @@ -63,13 +60,6 @@ class CustomSwitch: UISwitch { } @objc private func valueChanged(_ sender: Any) { - if #available(iOS 13, *) { - updateThumbColor(isOn: isOn, animated: true) - } else { - // Wait for animations to finish before changing the thumb color to prevent the jumpy behaviour. - CATransaction.setCompletionBlock { - self.updateThumbColor(isOn: self.isOn, animated: false) - } - } + updateThumbColor(isOn: isOn, animated: true) } } diff --git a/ios/MullvadVPN/CustomSwitchContainer.swift b/ios/MullvadVPN/CustomSwitchContainer.swift index 55316f2929..6fdf06a2a3 100644 --- a/ios/MullvadVPN/CustomSwitchContainer.swift +++ b/ios/MullvadVPN/CustomSwitchContainer.swift @@ -15,9 +15,7 @@ class CustomSwitchContainer: UIView { let shapeLayer = CAShapeLayer() shapeLayer.borderColor = UIColor.Switch.borderColor.cgColor shapeLayer.borderWidth = 2 - if #available(iOS 13.0, *) { - shapeLayer.cornerCurve = .continuous - } + shapeLayer.cornerCurve = .continuous return shapeLayer }() diff --git a/ios/MullvadVPN/DeviceRowView.swift b/ios/MullvadVPN/DeviceRowView.swift index c35f2f78db..ac638f47ab 100644 --- a/ios/MullvadVPN/DeviceRowView.swift +++ b/ios/MullvadVPN/DeviceRowView.swift @@ -28,7 +28,7 @@ class DeviceRowView: UIView { let removeButton: UIButton = { let image = UIImage(named: "IconClose")? - .backport_withTintColor( + .withTintColor( .white.withAlphaComponent(0.4), renderingMode: .alwaysOriginal ) diff --git a/ios/MullvadVPN/HeaderBarView.swift b/ios/MullvadVPN/HeaderBarView.swift index d27fb6ef6c..467bdb37da 100644 --- a/ios/MullvadVPN/HeaderBarView.swift +++ b/ios/MullvadVPN/HeaderBarView.swift @@ -11,7 +11,7 @@ import UIKit class HeaderBarView: UIView { private let brandNameImage = UIImage(named: "LogoText")? - .backport_withTintColor(UIColor.HeaderBar.brandNameColor, renderingMode: .alwaysOriginal) + .withTintColor(UIColor.HeaderBar.brandNameColor, renderingMode: .alwaysOriginal) let logoImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "LogoIcon")) @@ -30,9 +30,9 @@ class HeaderBarView: UIView { class func makeSettingsButton() -> HeaderBarButton { let settingsImage = UIImage(named: "IconSettings")? - .backport_withTintColor(UIColor.HeaderBar.buttonColor, renderingMode: .alwaysOriginal) + .withTintColor(UIColor.HeaderBar.buttonColor, renderingMode: .alwaysOriginal) let disabledSettingsImage = UIImage(named: "IconSettings")? - .backport_withTintColor( + .withTintColor( UIColor.HeaderBar.disabledButtonColor, renderingMode: .alwaysOriginal ) @@ -77,9 +77,7 @@ class HeaderBarView: UIView { right: UIMetrics.contentLayoutMargins.right ) - if #available(iOS 13.0, *) { - accessibilityContainerType = .semanticGroup - } + accessibilityContainerType = .semanticGroup let imageSize = brandNameImage?.size ?? .zero let brandNameAspectRatio = imageSize.width / max(imageSize.height, 1) diff --git a/ios/MullvadVPN/NotificationBannerView.swift b/ios/MullvadVPN/NotificationBannerView.swift index bd74ee3dbf..325230d8a6 100644 --- a/ios/MullvadVPN/NotificationBannerView.swift +++ b/ios/MullvadVPN/NotificationBannerView.swift @@ -66,9 +66,7 @@ class NotificationBannerView: UIView { view.translatesAutoresizingMaskIntoConstraints = false view.backgroundColor = .dangerColor view.layer.cornerRadius = NotificationBannerView.indicatorViewSize.width * 0.5 - if #available(iOS 13.0, *) { - view.layer.cornerCurve = .circular - } + view.layer.cornerCurve = .circular return view }() diff --git a/ios/MullvadVPN/OutOfTimeViewController.swift b/ios/MullvadVPN/OutOfTimeViewController.swift index b37a1b0eb5..6c7700a6f2 100644 --- a/ios/MullvadVPN/OutOfTimeViewController.swift +++ b/ios/MullvadVPN/OutOfTimeViewController.swift @@ -185,9 +185,8 @@ private extension OutOfTimeViewController { } view.isUserInteractionEnabled = isInteractionEnabled - if #available(iOS 13.0, *) { - isModalInPresentation = !isInteractionEnabled - } + isModalInPresentation = !isInteractionEnabled + navigationItem.setHidesBackButton(!isInteractionEnabled, animated: animated) } diff --git a/ios/MullvadVPN/PreferencesViewController.swift b/ios/MullvadVPN/PreferencesViewController.swift index 152545b20d..4b148a5556 100644 --- a/ios/MullvadVPN/PreferencesViewController.swift +++ b/ios/MullvadVPN/PreferencesViewController.swift @@ -54,12 +54,8 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel navigationItem.setHidesBackButton(editing, animated: animated) - if #available(iOS 13.0, *) { - // Disable swipe to dismiss when editing - isModalInPresentation = editing - } else { - // no-op - } + // Disable swipe to dismiss when editing + isModalInPresentation = editing super.setEditing(editing, animated: animated) } diff --git a/ios/MullvadVPN/ProblemReportReviewViewController.swift b/ios/MullvadVPN/ProblemReportReviewViewController.swift index cbe2956746..9a4d69b5d8 100644 --- a/ios/MullvadVPN/ProblemReportReviewViewController.swift +++ b/ios/MullvadVPN/ProblemReportReviewViewController.swift @@ -43,7 +43,7 @@ class ProblemReportReviewViewController: UIViewController { textView.translatesAutoresizingMaskIntoConstraints = false textView.text = reportString textView.isEditable = false - textView.font = UIFont.backport_monospacedSystemFont( + textView.font = UIFont.monospacedSystemFont( ofSize: UIFont.systemFontSize, weight: .regular ) diff --git a/ios/MullvadVPN/ProblemReportViewController.swift b/ios/MullvadVPN/ProblemReportViewController.swift index 1c20ddedc0..c2e4958004 100644 --- a/ios/MullvadVPN/ProblemReportViewController.swift +++ b/ios/MullvadVPN/ProblemReportViewController.swift @@ -218,9 +218,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit scrollViewKeyboardResponder = AutomaticKeyboardResponder(targetView: scrollView) // Make sure that the user can't easily dismiss the controller on iOS 13 and above - if #available(iOS 13.0, *) { - isModalInPresentation = true - } + isModalInPresentation = true // Set hugging & compression priorities so that description text view wants to grow emailTextField.setContentHuggingPriority(.defaultHigh, for: .vertical) diff --git a/ios/MullvadVPN/REST/HTTP.swift b/ios/MullvadVPN/REST/HTTP.swift index 85995c43ce..f6e8ff247d 100644 --- a/ios/MullvadVPN/REST/HTTP.swift +++ b/ios/MullvadVPN/REST/HTTP.swift @@ -48,18 +48,3 @@ enum HTTPHeader { static let etag = "ETag" static let ifNoneMatch = "If-None-Match" } - -extension HTTPURLResponse { - func value(forCaseInsensitiveHTTPHeaderField headerField: String) -> String? { - if #available(iOS 13.0, *) { - return self.value(forHTTPHeaderField: headerField) - } else { - for case let key as String in allHeaderFields.keys { - if case .orderedSame = key.caseInsensitiveCompare(headerField) { - return self.allHeaderFields[key] as? String - } - } - return nil - } - } -} diff --git a/ios/MullvadVPN/REST/RESTAPIProxy.swift b/ios/MullvadVPN/REST/RESTAPIProxy.swift index a53b95b8ac..9d94038f87 100644 --- a/ios/MullvadVPN/REST/RESTAPIProxy.swift +++ b/ios/MullvadVPN/REST/RESTAPIProxy.swift @@ -81,8 +81,7 @@ extension REST { ServerRelaysResponse.self, from: data ) - let newEtag = response - .value(forCaseInsensitiveHTTPHeaderField: HTTPHeader.etag) + let newEtag = response.value(forHTTPHeaderField: HTTPHeader.etag) return .newContent(newEtag, serverRelays) } diff --git a/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift b/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift deleted file mode 100644 index e9bcf01c62..0000000000 --- a/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// Result+UIBackgroundFetchResult.swift -// Result+UIBackgroundFetchResult -// -// Created by pronebird on 07/09/2021. -// Copyright © 2021 Mullvad VPN AB. All rights reserved. -// - -import UIKit - -extension OperationCompletion { - func backgroundFetchResult(_ hasNewData: (Success) -> Bool) -> UIBackgroundFetchResult { - switch self { - case let .success(value): - return hasNewData(value) ? .newData : .noData - case .cancelled: - return .noData - case .failure: - return .failed - } - } -} - -extension UIBackgroundFetchResult: CustomStringConvertible { - public var description: String { - switch self { - case .newData: - return "new data" - case .noData: - return "no data" - case .failed: - return "failed" - @unknown default: - return "unknown (rawValue: \(rawValue)" - } - } - - func combine(with others: [UIBackgroundFetchResult]) -> UIBackgroundFetchResult { - return others.reduce(self) { partialResult, other in - return partialResult.combine(with: other) - } - } - - func combine(with other: UIBackgroundFetchResult) -> UIBackgroundFetchResult { - if self == .failed || other == .failed { - return .failed - } else if self == .newData || other == .newData { - return .newData - } else { - return .noData - } - } -} diff --git a/ios/MullvadVPN/SceneDelegate.swift b/ios/MullvadVPN/SceneDelegate.swift index fc6951e0d5..a12513d6b8 100644 --- a/ios/MullvadVPN/SceneDelegate.swift +++ b/ios/MullvadVPN/SceneDelegate.swift @@ -30,12 +30,6 @@ class SceneDelegate: UIResponder { private var accountDataThrottling = AccountDataThrottling() private var outOfTimeTimer: Timer? - override init() { - super.init() - - addSceneEvents() - } - deinit { clearOutOfTimeTimer() } @@ -106,33 +100,6 @@ class SceneDelegate: UIResponder { } } - private func addSceneEvents() { - if #available(iOS 13, *) { - // no-op - } else { - let notificationCenter = NotificationCenter.default - - notificationCenter.addObserver( - self, - selector: #selector(sceneDidBecomeActive), - name: UIApplication.didBecomeActiveNotification, - object: nil - ) - notificationCenter.addObserver( - self, - selector: #selector(sceneDidEnterBackground), - name: UIApplication.didEnterBackgroundNotification, - object: nil - ) - notificationCenter.addObserver( - self, - selector: #selector(sceneWillResignActive), - name: UIApplication.willResignActiveNotification, - object: nil - ) - } - } - @objc private func sceneDidBecomeActive() { TunnelManager.shared.refreshTunnelStatus() @@ -161,17 +128,14 @@ class SceneDelegate: UIResponder { } @objc private func sceneDidEnterBackground() { - if #available(iOS 13, *) { - let appDelegate = UIApplication.shared.delegate as? AppDelegate + let appDelegate = UIApplication.shared.delegate as? AppDelegate - appDelegate?.scheduleBackgroundTasks() - } + appDelegate?.scheduleBackgroundTasks() } } // MARK: - UIWindowSceneDelegate -@available(iOS 13.0, *) extension SceneDelegate: UIWindowSceneDelegate { func scene( _ scene: UIScene, @@ -366,10 +330,7 @@ extension SceneDelegate { modalRootContainer.preferredContentSize = CGSize(width: 480, height: 600) modalRootContainer.modalPresentationStyle = .formSheet modalRootContainer.presentationController?.delegate = self - - if #available(iOS 13.0, *) { - modalRootContainer.isModalInPresentation = true - } + modalRootContainer.isModalInPresentation = true if modalRootContainer.presentingViewController == nil { rootContainer.present(modalRootContainer, animated: animated) @@ -473,9 +434,7 @@ extension SceneDelegate { if UIDevice.current.userInterfaceIdiom == .pad { controller.modalPresentationStyle = .formSheet - if #available(iOS 13.0, *) { - controller.isModalInPresentation = true - } + controller.isModalInPresentation = true } controller.completionHandler = { controller in @@ -1019,7 +978,6 @@ struct ClassicWindowFactory: WindowFactory { } } -@available(iOS 13.0, *) struct SceneWindowFactory: WindowFactory { let windowScene: UIWindowScene diff --git a/ios/MullvadVPN/SelectLocationCell.swift b/ios/MullvadVPN/SelectLocationCell.swift index c2050560c7..7622433925 100644 --- a/ios/MullvadVPN/SelectLocationCell.swift +++ b/ios/MullvadVPN/SelectLocationCell.swift @@ -18,9 +18,7 @@ class SelectLocationCell: UITableViewCell { let statusIndicator: UIView = { let view = UIView() view.layer.cornerRadius = kRelayIndicatorSize * 0.5 - if #available(iOS 13.0, *) { - view.layer.cornerCurve = .circular - } + view.layer.cornerCurve = .circular return view }() diff --git a/ios/MullvadVPN/SelectLocationNavigationController.swift b/ios/MullvadVPN/SelectLocationNavigationController.swift index b2e6605aec..a88c87c907 100644 --- a/ios/MullvadVPN/SelectLocationNavigationController.swift +++ b/ios/MullvadVPN/SelectLocationNavigationController.swift @@ -24,12 +24,6 @@ class SelectLocationNavigationController: UINavigationController { viewControllers = [contentController] } - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { - // This initializer exists to prevent crash on iOS 12. - // See: https://stackoverflow.com/a/38335090/351305 - super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) - } - required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/ios/MullvadVPN/SettingsCell.swift b/ios/MullvadVPN/SettingsCell.swift index 99fe94d4d7..b642549d5a 100644 --- a/ios/MullvadVPN/SettingsCell.swift +++ b/ios/MullvadVPN/SettingsCell.swift @@ -37,7 +37,7 @@ class SettingsCell: UITableViewCell { didSet { accessoryType = .none - let image = disclosureType.image?.backport_withTintColor( + let image = disclosureType.image?.withTintColor( UIColor.Cell.disclosureIndicatorColor, renderingMode: .alwaysOriginal ) @@ -115,16 +115,6 @@ class SettingsCell: UITableViewCell { setLayoutMargins() } - override func layoutSubviews() { - super.layoutSubviews() - - if #available(iOS 13, *) { - // no-op - } else { - layoutSubviews_iOS12() - } - } - private func setLayoutMargins() { // Set layout margins for standard acceessories added into the cell (reorder control, etc..) layoutMargins = UIMetrics.settingsCellLayoutMargins @@ -132,40 +122,4 @@ class SettingsCell: UITableViewCell { // Set layout margins for cell content contentView.layoutMargins = UIMetrics.settingsCellLayoutMargins } - - /// On iOS 12, standard edit and reorder controls do not respect layout margins. - /// This method does layout adjustments to fix that. - private func layoutSubviews_iOS12() { - guard isEditing || showsReorderControl else { return } - - var leftOffset: CGFloat = 0 - var rightOffset: CGFloat = 0 - - for subview in subviews { - // Detect the edit control and move it, so that the nested image view is aligned along the left edge of the - // layout margins. - if subview.description.starts(with: "<UITableViewCellEditControl"), - let imageView = subview.subviews.first - { - let imageOffset = imageView.frame.minX - var pos = subview.frame.origin - pos.x = layoutMargins.left - imageOffset - subview.frame.origin = pos - leftOffset = pos.x - } - - // Detect the reorder control and move it, so that its right edge is aligned along the right edge of the - // layout margins. - if subview.description.starts(with: "<UITableViewCellReorderControl") { - var pos = subview.frame.origin - pos.x -= layoutMargins.right - subview.frame.origin = pos - rightOffset = layoutMargins.right - } - } - - // Adjust the content view to account for the adjustments to the edit and reorder controls. - let contentInset = UIEdgeInsets(top: 0, left: leftOffset, bottom: 0, right: rightOffset) - contentView.frame = contentView.frame.inset(by: contentInset) - } } diff --git a/ios/MullvadVPN/SettingsDNSTextCell.swift b/ios/MullvadVPN/SettingsDNSTextCell.swift index dd1a97ccd3..83764fe9ee 100644 --- a/ios/MullvadVPN/SettingsDNSTextCell.swift +++ b/ios/MullvadVPN/SettingsDNSTextCell.swift @@ -56,9 +56,7 @@ class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate { backgroundView?.backgroundColor = UIColor.TextField.backgroundColor contentView.addSubview(textField) - if #available(iOS 13.0, *) { - overrideUserInterfaceStyle = .light - } + overrideUserInterfaceStyle = .light NSLayoutConstraint.activate([ textField.topAnchor.constraint(equalTo: contentView.topAnchor), diff --git a/ios/MullvadVPN/SettingsNavigationController.swift b/ios/MullvadVPN/SettingsNavigationController.swift index 0476ac23fa..58993fc6c4 100644 --- a/ios/MullvadVPN/SettingsNavigationController.swift +++ b/ios/MullvadVPN/SettingsNavigationController.swift @@ -56,12 +56,6 @@ class SettingsNavigationController: CustomNavigationController, SettingsViewCont pushViewController(makeViewController(for: .root), animated: false) } - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { - // This initializer exists to prevent crash on iOS 12. - // See: https://stackoverflow.com/a/38335090/351305 - super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) - } - required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } diff --git a/ios/MullvadVPN/SpinnerActivityIndicatorView.swift b/ios/MullvadVPN/SpinnerActivityIndicatorView.swift index f09cd507e7..344c46e125 100644 --- a/ios/MullvadVPN/SpinnerActivityIndicatorView.swift +++ b/ios/MullvadVPN/SpinnerActivityIndicatorView.swift @@ -104,21 +104,11 @@ class SpinnerActivityIndicatorView: UIView { } private func registerSceneActivationObserver() { - let name: NSNotification.Name - var object: Any? - - if #available(iOS 13, *) { - name = UIScene.willEnterForegroundNotification - object = window?.windowScene - } else { - name = UIApplication.willEnterForegroundNotification - } - unregisterSceneActivationObserver() sceneActivationObserver = NotificationCenter.default.addObserver( - forName: name, - object: object, + forName: UIScene.willEnterForegroundNotification, + object: window?.windowScene, queue: .main, using: { [weak self] _ in self?.restartAnimationIfNeeded() } diff --git a/ios/MullvadVPN/TranslucentButtonBlurView.swift b/ios/MullvadVPN/TranslucentButtonBlurView.swift index d10e606baf..496dd1e100 100644 --- a/ios/MullvadVPN/TranslucentButtonBlurView.swift +++ b/ios/MullvadVPN/TranslucentButtonBlurView.swift @@ -57,11 +57,7 @@ private extension AppButton.Style { var blurEffectStyle: UIBlurEffect.Style { switch self { case .translucentDangerSplitLeft, .translucentDangerSplitRight, .translucentDanger: - if #available(iOS 13.0, *) { - return .systemUltraThinMaterialDark - } else { - return .dark - } + return .systemUltraThinMaterialDark default: return .light } diff --git a/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift b/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift index f42e7a2f7b..ca17e2510a 100644 --- a/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift +++ b/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift @@ -31,7 +31,6 @@ extension UIBarButtonItem { } } - @available(iOS 13, *) fileprivate var systemImage: UIImage? { switch self { case .previous: @@ -47,21 +46,13 @@ extension UIBarButtonItem { target: Any?, action: Selector? ) { - if #available(iOS 13, *) { - self.init( - image: keyboardNavigationItemType.systemImage, - style: .plain, - target: target, - action: action - ) - } else { - self.init( - title: keyboardNavigationItemType.localizedTitle, - style: .plain, - target: target, - action: action - ) - } + self.init( + image: keyboardNavigationItemType.systemImage, + style: .plain, + target: target, + action: action + ) + accessibilityLabel = keyboardNavigationItemType.localizedTitle } @@ -82,13 +73,9 @@ extension UIBarButtonItem { configurationBlock(prevButton, nextButton) - if #available(iOS 13, *) { - let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) - spacer.width = 8 + let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) + spacer.width = 8 - return [prevButton, spacer, nextButton] - } else { - return [prevButton, nextButton] - } + return [prevButton, spacer, nextButton] } } diff --git a/ios/MullvadVPN/UIFont+Monospaced.swift b/ios/MullvadVPN/UIFont+Monospaced.swift deleted file mode 100644 index 0690070e01..0000000000 --- a/ios/MullvadVPN/UIFont+Monospaced.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// UIFont+Monospaced.swift -// MullvadVPN -// -// Created by pronebird on 28/06/2022. -// Copyright © 2022 Mullvad VPN AB. All rights reserved. -// - -import UIKit - -extension UIFont { - class func backport_monospacedSystemFont(ofSize size: CGFloat, weight: UIFont.Weight) -> UIFont - { - if #available(iOS 13, *) { - return UIFont.monospacedSystemFont(ofSize: size, weight: weight) - } else { - let fontDescriptor = UIFontDescriptor(fontAttributes: [ - .name: "Menlo", - .traits: [ - UIFontDescriptor.TraitKey.weight: weight, - ], - ]) - - return UIFont(descriptor: fontDescriptor, size: size) - } - } -} diff --git a/ios/MullvadVPN/UIImage+TintColor.swift b/ios/MullvadVPN/UIImage+TintColor.swift deleted file mode 100644 index 46fd6326bf..0000000000 --- a/ios/MullvadVPN/UIImage+TintColor.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// UIImage+TintColor.swift -// MullvadVPN -// -// Created by pronebird on 17/11/2021. -// Copyright © 2021 Mullvad VPN AB. All rights reserved. -// - -import UIKit - -extension UIImage { - func backport_withTintColor(_ tintColor: UIColor) -> UIImage { - return backport_withTintColor(tintColor, renderingMode: renderingMode) - } - - func backport_withTintColor(_ tintColor: UIColor, renderingMode: RenderingMode) -> UIImage { - if #available(iOS 13, *) { - return withTintColor(tintColor, renderingMode: renderingMode) - } - - let rect = CGRect(origin: .zero, size: size) - let renderer = UIGraphicsImageRenderer(size: size) - - let renderedImage = renderer.image { context in - tintColor.setFill() - context.fill(rect) - draw(in: rect, blendMode: .destinationIn, alpha: 1) - } - - return renderedImage.withRenderingMode(renderingMode) - } -} |
