From 7509670dd5d5cf3082feeb508ea5b3aabf5430cc Mon Sep 17 00:00:00 2001 From: Jon Petersson Date: Mon, 4 Sep 2023 23:53:38 +0200 Subject: [PATCH 1/2] Fix or report all current smaller Swiftlint warnings in xcode --- ios/.swiftlint.yml | 7 +++- ios/MullvadVPN.xcodeproj/project.pbxproj | 7 ++-- ios/MullvadVPN/AppDelegate.swift | 3 +- .../Classes/AutomaticKeyboardResponder.swift | 4 ++- .../Classes/ConsolidatedApplicationLog.swift | 1 + .../Classes/InputTextFormatter.swift | 13 ++----- .../Root/RootContainerViewController.swift | 2 ++ .../Coordinators/ApplicationCoordinator.swift | 2 ++ .../Coordinators/WelcomeCoordinator.swift | 2 +- .../NSRegularExpression+IPAddress.swift | 2 ++ .../Notifications/NotificationManager.swift | 5 ++- ios/MullvadVPN/SceneDelegate.swift | 1 + .../SimulatorTunnelProvider.swift | 1 + .../TunnelManager/SetAccountOperation.swift | 16 ++------- ios/MullvadVPN/TunnelManager/Tunnel.swift | 4 +-- .../TunnelManager/TunnelManager.swift | 1 - ios/MullvadVPN/UI appearance/UIMetrics.swift | 23 +++++++----- .../Login/AccountInputGroupView.swift | 2 ++ .../Login/LoginViewController.swift | 2 ++ .../OutOfTime/OutOfTimeViewController.swift | 10 ++++-- .../PreferencesViewController.swift | 20 ++++++++--- .../Preferences/PreferencesViewModel.swift | 8 +++-- .../ProblemReportInteractor.swift | 3 -- .../ProblemReportViewController.swift | 25 +++++++++---- .../SelectLocation/LocationDataSource.swift | 2 ++ .../SelectLocation/SelectLocationCell.swift | 12 ++----- .../Settings/SettingsCell.swift | 6 +--- .../TermsOfServiceContentView.swift | 6 ++-- .../Tunnel/ConnectionPanelView.swift | 2 +- .../Tunnel/DisconnectSplitButton.swift | 5 ++- .../Tunnel/TunnelControlView.swift | 2 ++ ios/MullvadVPN/Views/AppButton.swift | 1 + .../DeviceCheckOperationTests.swift | 2 ++ ios/Operations/AsyncOperation.swift | 27 ++------------ .../OperationBlockObserverSupport.swift | 35 +++++++++++++++++++ ios/PacketTunnel/PacketTunnelProvider.swift | 2 ++ ios/PacketTunnelCore/Pinger/Pinger.swift | 2 ++ .../TunnelMonitor/TunnelMonitor.swift | 2 ++ .../TunnelMonitorTests.swift | 2 +- 39 files changed, 166 insertions(+), 106 deletions(-) create mode 100644 ios/Operations/OperationBlockObserverSupport.swift diff --git a/ios/.swiftlint.yml b/ios/.swiftlint.yml index b5634621a301..9e7704961d8c 100644 --- a/ios/.swiftlint.yml +++ b/ios/.swiftlint.yml @@ -35,7 +35,8 @@ line_length: type_name: min_length: 4 max_length: - error: 50 + warning: 50 + error: 60 excluded: iPhone # excluded via string allowed_symbols: ["_"] # these are allowed in type names identifier_name: @@ -47,3 +48,7 @@ identifier_name: - URL - GlobalAPIKey reporter: "xcode" +nesting: + type_level: + warning: 2 + error: 4 diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 27f16941746a..ccf1018d0526 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -395,6 +395,7 @@ 7A21DACF2A30AA3700A787A9 /* UITextField+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A21DACE2A30AA3700A787A9 /* UITextField+Appearance.swift */; }; 7A307AD92A8CD8DA0017618B /* Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A307AD82A8CD8DA0017618B /* Duration.swift */; }; 7A307ADB2A8F56DF0017618B /* Duration+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A307ADA2A8F56DF0017618B /* Duration+Extensions.swift */; }; + 7A3353972AAA0F8600F0A71C /* OperationBlockObserverSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3353962AAA0F8600F0A71C /* OperationBlockObserverSupport.swift */; }; 7A42DEC92A05164100B209BE /* SettingsInputCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A42DEC82A05164100B209BE /* SettingsInputCell.swift */; }; 7A42DECD2A09064C00B209BE /* SelectableSettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A42DECC2A09064C00B209BE /* SelectableSettingsCell.swift */; }; 7A7AD28D29DC677800480EF1 /* FirstTimeLaunch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7AD28C29DC677800480EF1 /* FirstTimeLaunch.swift */; }; @@ -1311,6 +1312,7 @@ 7A21DACE2A30AA3700A787A9 /* UITextField+Appearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextField+Appearance.swift"; sourceTree = ""; }; 7A307AD82A8CD8DA0017618B /* Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Duration.swift; sourceTree = ""; }; 7A307ADA2A8F56DF0017618B /* Duration+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Duration+Extensions.swift"; sourceTree = ""; }; + 7A3353962AAA0F8600F0A71C /* OperationBlockObserverSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationBlockObserverSupport.swift; sourceTree = ""; }; 7A42DEC82A05164100B209BE /* SettingsInputCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInputCell.swift; sourceTree = ""; }; 7A42DECC2A09064C00B209BE /* SelectableSettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectableSettingsCell.swift; sourceTree = ""; }; 7A7AD28C29DC677800480EF1 /* FirstTimeLaunch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstTimeLaunch.swift; sourceTree = ""; }; @@ -2456,8 +2458,9 @@ 581813A628E09DF2002817DE /* MutuallyExclusive.swift */, 581813A028E09DBB002817DE /* NoCancelledDependenciesCondition.swift */, 581813A228E09DCD002817DE /* NoFailedDependenciesCondition.swift */, - 5840BE34279EDB16002836BA /* OperationError.swift */, + 7A3353962AAA0F8600F0A71C /* OperationBlockObserverSupport.swift */, 589D28772846250500F9A7B3 /* OperationCondition.swift */, + 5840BE34279EDB16002836BA /* OperationError.swift */, 589D28792846250500F9A7B3 /* OperationObserver.swift */, 58059DDD28468158002B1049 /* OutputOperation.swift */, 5842102D282D3FC200F24E46 /* ResultBlockOperation.swift */, @@ -4010,6 +4013,7 @@ 58D223BB294C8A630029F5F8 /* NoCancelledDependenciesCondition.swift in Sources */, 58D223B3294C8A630029F5F8 /* OperationObserver.swift in Sources */, 58D223B7294C8A630029F5F8 /* MutuallyExclusive.swift in Sources */, + 7A3353972AAA0F8600F0A71C /* OperationBlockObserverSupport.swift in Sources */, 58D223B2294C8A630029F5F8 /* OperationError.swift in Sources */, 58D223AF294C8A630029F5F8 /* NoFailedDependenciesCondition.swift in Sources */, 58D223B9294C8A630029F5F8 /* AsyncOperationQueue.swift in Sources */, @@ -4077,7 +4081,6 @@ 58B465702A98C53300467203 /* RequestExecutorTests.swift in Sources */, A917352129FAAA5200D5DCFD /* TransportStrategyTests.swift in Sources */, 58FBFBE9291622580020E046 /* ExponentialBackoffTests.swift in Sources */, - 58FBFBF1291630700020E046 /* DurationTests.swift in Sources */, 58BDEB9D2A98F69E00F578F2 /* MemoryCache.swift in Sources */, 58BDEB9B2A98F58600F578F2 /* TimeServerProxy.swift in Sources */, 58BDEB992A98F4ED00F578F2 /* AnyTransport.swift in Sources */, diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index 4c99cfd85765..46d913e381e7 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -405,7 +405,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let initTunnelManagerOperation = AsyncBlockOperation(dispatchQueue: .main) { finish in self.tunnelManager.loadConfiguration { error in - // TODO: avoid throwing fatal error and show the problem report UI instead. if let error { fatalError(error.localizedDescription) } @@ -492,4 +491,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD ) { completionHandler([.list, .banner, .sound]) } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/Classes/AutomaticKeyboardResponder.swift b/ios/MullvadVPN/Classes/AutomaticKeyboardResponder.swift index 99db0e966ebe..7a32ccf02230 100644 --- a/ios/MullvadVPN/Classes/AutomaticKeyboardResponder.swift +++ b/ios/MullvadVPN/Classes/AutomaticKeyboardResponder.swift @@ -21,7 +21,9 @@ class AutomaticKeyboardResponder { init(targetView: T, handler: @escaping (T, CGFloat) -> Void) { self.targetView = targetView self.handler = { view, adjustment in - handler(view as! T, adjustment) + if let view = view as? T { + handler(view, adjustment) + } } NotificationCenter.default.addObserver( diff --git a/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift b/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift index 22b9ec86f0bc..f6f5f0956fcb 100644 --- a/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift +++ b/ios/MullvadVPN/Classes/ConsolidatedApplicationLog.swift @@ -176,6 +176,7 @@ class ConsolidatedApplicationLog: TextOutputStreamable { private static func redactAccountNumber(string: String) -> String { redact( + // swiftlint:disable:next force_try regularExpression: try! NSRegularExpression(pattern: #"\d{16}"#), string: string, replacementString: kRedactedAccountPlaceholder diff --git a/ios/MullvadVPN/Classes/InputTextFormatter.swift b/ios/MullvadVPN/Classes/InputTextFormatter.swift index acb95e7960e7..c9a0cb88c59e 100644 --- a/ios/MullvadVPN/Classes/InputTextFormatter.swift +++ b/ios/MullvadVPN/Classes/InputTextFormatter.swift @@ -75,8 +75,7 @@ class InputTextFormatter: NSObject, UITextFieldDelegate, UITextPasteDelegate { // Since removing separator alone makes no sense, this computation extends the string range // to include the digit preceding a separator. - if replacementString.isEmpty, emptySelection, - !formattedString.isEmpty { + if replacementString.isEmpty, emptySelection, !formattedString.isEmpty { let precedingDigitIndex = formattedString .prefix(through: stringRange.lowerBound) .lastIndex { isAllowed($0) } ?? formattedString.startIndex @@ -85,19 +84,13 @@ class InputTextFormatter: NSObject, UITextFieldDelegate, UITextPasteDelegate { } // Replace the given range within a formatted string - let newString = formattedString.replacingCharacters( - in: stringRange, - with: replacementString - ) + let newString = formattedString.replacingCharacters(in: stringRange, with: replacementString) // Number of digits within a string var numDigits = 0 // Insertion location within the input string - let insertionLocation = formattedString.distance( - from: formattedString.startIndex, - to: stringRange.lowerBound - ) + let insertionLocation = formattedString.distance(from: formattedString.startIndex, to: stringRange.lowerBound) // Original caret location based on insertion location + number of characters added let originalCaretPosition = insertionLocation + replacementString.count diff --git a/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift b/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift index afb28ce12499..5b2f167d7d41 100644 --- a/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift +++ b/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift @@ -840,4 +840,6 @@ extension RootContainerViewController { presentationContainerAccountButton?.isHidden = !configuration.showsAccountButton headerBarView.update(configuration: configuration) } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift index 2c4a0cacab15..ae302ea87d36 100644 --- a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift @@ -979,4 +979,6 @@ fileprivate extension AppPreferencesDataSource { mutating func markChangeLogSeen() { self.lastSeenChangeLogVersion = Bundle.main.shortVersion } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift index 33a09b41718e..de341fbce850 100644 --- a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift @@ -96,7 +96,7 @@ extension WelcomeCoordinator: WelcomeViewControllerDelegate { """ let alertController = CustomAlertViewController( message: NSLocalizedString( - "WELCOME_DEVICE_CONCEPET_TEXT_DIALOG", + "WELCOME_DEVICE_CONCEPT_TEXT_DIALOG", tableName: "Welcome", value: message, comment: "" diff --git a/ios/MullvadVPN/Extensions/NSRegularExpression+IPAddress.swift b/ios/MullvadVPN/Extensions/NSRegularExpression+IPAddress.swift index 7cb5ae90da59..155de03d0a38 100644 --- a/ios/MullvadVPN/Extensions/NSRegularExpression+IPAddress.swift +++ b/ios/MullvadVPN/Extensions/NSRegularExpression+IPAddress.swift @@ -22,6 +22,7 @@ extension NSRegularExpression { return try! NSRegularExpression(pattern: pattern, options: [.allowCommentsAndWhitespace]) } + // swiftlint:disable line_length static var ipv6RegularExpression: NSRegularExpression { // Regular expression obtained from: // https://stackoverflow.com/a/17871737 @@ -49,4 +50,5 @@ extension NSRegularExpression { // swiftlint:disable:next force_try return try! NSRegularExpression(pattern: pattern, options: [.allowCommentsAndWhitespace]) } + // swiftlint:enable line_length } diff --git a/ios/MullvadVPN/Notifications/NotificationManager.swift b/ios/MullvadVPN/Notifications/NotificationManager.swift index 11da16407f34..3f722a628028 100644 --- a/ios/MullvadVPN/Notifications/NotificationManager.swift +++ b/ios/MullvadVPN/Notifications/NotificationManager.swift @@ -207,7 +207,10 @@ final class NotificationManager: NotificationProviderDelegate { } } - // Invalidate in-app notification + invalidateInAppNotification(notificationProvider) + } + + private func invalidateInAppNotification(_ notificationProvider: NotificationProvider) { if let notificationProvider = notificationProvider as? InAppNotificationProvider { var newNotificationDescriptors = inAppNotificationDescriptors diff --git a/ios/MullvadVPN/SceneDelegate.swift b/ios/MullvadVPN/SceneDelegate.swift index 4720556fe4b2..c1e9b91f9c4a 100644 --- a/ios/MullvadVPN/SceneDelegate.swift +++ b/ios/MullvadVPN/SceneDelegate.swift @@ -27,6 +27,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, SettingsMigrationUIHand private var tunnelObserver: TunnelObserver? private var appDelegate: AppDelegate { + // swiftlint:disable:next force_cast UIApplication.shared.delegate as! AppDelegate } diff --git a/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProvider.swift b/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProvider.swift index 637e0ad5f34d..a2eb3d5f4314 100644 --- a/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProvider.swift +++ b/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProvider.swift @@ -423,4 +423,5 @@ final class SimulatorTunnelProviderManager: NSObject, VPNTunnelProviderManagerPr } } +// swiftlint:disable:next file_length #endif diff --git a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift index 108b6be81bc9..080fdc36ab9e 100644 --- a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift +++ b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift @@ -216,10 +216,7 @@ class SetAccountOperation: ResultOperation { let result = result.inspectError { error in guard !error.isOperationCancellationError else { return } - logger.error( - error: error, - message: "Failed to create new account." - ) + logger.error(error: error, message: "Failed to create new account.") }.map { newAccountData -> StoredAccountData in logger.debug("Created new account.") @@ -322,10 +319,7 @@ class SetAccountOperation: ResultOperation { dispatchQueue.async { [self] in // Ignore error but log it. if let error { - logger.error( - error: error, - message: "Failed to remove VPN configuration." - ) + logger.error(error: error, message: "Failed to remove VPN configuration.") } interactor.setTunnel(nil, shouldRefreshTunnelState: false) @@ -338,11 +332,7 @@ class SetAccountOperation: ResultOperation { /// Create new private key and create new device via API. private func createDevice(accountNumber: String, completion: @escaping (Result) -> Void) { let privateKey = PrivateKey() - - let request = REST.CreateDeviceRequest( - publicKey: privateKey.publicKey, - hijackDNS: false - ) + let request = REST.CreateDeviceRequest(publicKey: privateKey.publicKey, hijackDNS: false) logger.debug("Create device...") diff --git a/ios/MullvadVPN/TunnelManager/Tunnel.swift b/ios/MullvadVPN/TunnelManager/Tunnel.swift index fa830f1298d5..5a9990c8862d 100644 --- a/ios/MullvadVPN/TunnelManager/Tunnel.swift +++ b/ios/MullvadVPN/TunnelManager/Tunnel.swift @@ -108,9 +108,9 @@ final class Tunnel: Equatable { } func sendProviderMessage(_ messageData: Data, responseHandler: ((Data?) -> Void)?) throws { - let session = tunnelProvider.connection as! VPNTunnelProviderSessionProtocol + let session = tunnelProvider.connection as? VPNTunnelProviderSessionProtocol - try session.sendProviderMessage(messageData, responseHandler: responseHandler) + try session?.sendProviderMessage(messageData, responseHandler: responseHandler) } func setConfiguration(_ configuration: TunnelConfiguration) { diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift index 905aec844540..3e0d159de8c5 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift @@ -755,7 +755,6 @@ final class TunnelManager: StorePaymentObserver { } case .invalid: - // TODO: handle invalid account in some way? break } } diff --git a/ios/MullvadVPN/UI appearance/UIMetrics.swift b/ios/MullvadVPN/UI appearance/UIMetrics.swift index d3145a821fc3..b257d5d46a8d 100644 --- a/ios/MullvadVPN/UI appearance/UIMetrics.swift +++ b/ios/MullvadVPN/UI appearance/UIMetrics.swift @@ -53,6 +53,20 @@ enum UIMetrics { static let textFieldContentInsets = UIEdgeInsets(top: 8, left: 24, bottom: 8, right: 24) static let textFieldNonEditingContentInsetLeft: CGFloat = 40 } + + /// Group of constants related to in-app notifications banner. + enum InAppBannerNotification { + /// Layout margins for contents presented within the banner. + static let layoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24) + + /// Size of little round severity indicator. + static let indicatorSize = CGSize(width: 12, height: 12) + } + + enum DisconnectSplitButton { + static let secondaryButtonPhone = CGSize(width: 42, height: 42) + static let secondaryButtonPad = CGSize(width: 52, height: 52) + } } extension UIMetrics { @@ -83,15 +97,6 @@ extension UIMetrics { /// Common cell indentation width static let cellIndentationWidth: CGFloat = 16 - /// Group of constants related to in-app notifications banner. - enum InAppBannerNotification { - /// Layout margins for contents presented within the banner. - static let layoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24) - - /// Size of little round severity indicator. - static let indicatorSize = CGSize(width: 12, height: 12) - } - /// Spacing used in stack views of buttons static let interButtonSpacing: CGFloat = 16 diff --git a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift index 2a34644b6ddc..e5eb0ddb7794 100644 --- a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift +++ b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift @@ -552,4 +552,6 @@ private class AccountInputBorderLayer: CAShapeLayer { } return super.defaultAction(forKey: event) } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift index e7261079607e..94e51afb557c 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift @@ -433,4 +433,6 @@ private extension LoginState { return .hidden } } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeViewController.swift b/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeViewController.swift index 651886277f06..06b3dedb0bb3 100644 --- a/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeViewController.swift +++ b/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeViewController.swift @@ -156,7 +156,10 @@ class OutOfTimeViewController: UIViewController, RootContainment { NSLocalizedString( "OUT_OF_TIME_BODY_CONNECTED", tableName: "OutOfTime", - value: "You have no more VPN time left on this account. To add more, you will need to disconnect and access the Internet with an unsecure connection.", + value: """ + You have no more VPN time left on this account. To add more, you will need to \ + disconnect and access the Internet with an unsecure connection. + """, comment: "" ) ) @@ -165,7 +168,10 @@ class OutOfTimeViewController: UIViewController, RootContainment { NSLocalizedString( "OUT_OF_TIME_BODY_DISCONNECTED", tableName: "OutOfTime", - value: "You have no more VPN time left on this account. Either buy credit on our website or make an in-app purchase via the **Add 30 days time** button below.", + value: """ + You have no more VPN time left on this account. Either buy credit on our website \ + or make an in-app purchase via the **Add 30 days time** button below. + """, comment: "" ) ) diff --git a/ios/MullvadVPN/View controllers/Preferences/PreferencesViewController.swift b/ios/MullvadVPN/View controllers/Preferences/PreferencesViewController.swift index 5c23cf4dcfdc..ef05999fe4bb 100644 --- a/ios/MullvadVPN/View controllers/Preferences/PreferencesViewController.swift +++ b/ios/MullvadVPN/View controllers/Preferences/PreferencesViewController.swift @@ -117,6 +117,7 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel interactor.setDNSSettings(dnsSettings) } + // swiftlint:disable:next function_body_length func preferencesDataSource( _ dataSource: PreferencesDataSource, showInfo item: PreferencesDataSource.InfoButtonItem? @@ -128,7 +129,11 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel message = NSLocalizedString( "PREFERENCES_CONTENT_BLOCKERS_GENERAL", tableName: "ContentBlockers", - value: "When this feature is enabled it stops the device from contacting certain domains or websites known for distributing ads, malware, trackers and more. This might cause issues on certain websites, services, and programs.", + value: """ + When this feature is enabled it stops the device from contacting certain \ + domains or websites known for distributing ads, malware, trackers and more. \ + This might cause issues on certain websites, services, and programs. + """, comment: "" ) @@ -136,7 +141,10 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel message = NSLocalizedString( "PREFERENCES_CONTENT_BLOCKERS_MALWARE", tableName: "ContentBlockers", - value: "Warning: The malware blocker is not an anti-virus and should not be treated as such, this is just an extra layer of protection.", + value: """ + Warning: The malware blocker is not an anti-virus and should not \ + be treated as such, this is just an extra layer of protection. + """, comment: "" ) @@ -163,12 +171,15 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel ) #if DEBUG - case .wireGuardObfuscation: message = NSLocalizedString( "PREFERENCES_WIRE_GUARD_OBFUSCATION_GENERAL", tableName: "WireGuardObfuscation", - value: "Obfuscation hides the WireGuard traffic inside another protocol. It can be used to help circumvent censorship and other types of filtering, where a plain WireGuard connect would be blocked.", + value: """ + Obfuscation hides the WireGuard traffic inside another protocol. \ + It can be used to help circumvent censorship and other types of filtering, \ + where a plain WireGuard connect would be blocked. + """, comment: "" ) @@ -180,6 +191,7 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel comment: "" ) #endif + default: assertionFailure("No matching InfoButtonItem") } diff --git a/ios/MullvadVPN/View controllers/Preferences/PreferencesViewModel.swift b/ios/MullvadVPN/View controllers/Preferences/PreferencesViewModel.swift index 091be496a535..85a381606a94 100644 --- a/ios/MullvadVPN/View controllers/Preferences/PreferencesViewModel.swift +++ b/ios/MullvadVPN/View controllers/Preferences/PreferencesViewModel.swift @@ -53,7 +53,8 @@ enum CustomDNSPrecondition { "CUSTOM_DNS_NO_DNS_ENTRIES_EDITING_OFF_FOOTNOTE", tableName: "Preferences", value: "Tap **Edit** to add at least one DNS server.", - comment: "Foot note displayed if there are no DNS entries, but table view is not in editing mode." + comment: + "Foot note displayed if there are no DNS entries, but table view is not in editing mode." ), options: MarkdownStylingOptions(font: preferredFont) ) @@ -65,7 +66,10 @@ enum CustomDNSPrecondition { "CUSTOM_DNS_DISABLE_CONTENT_BLOCKERS_FOOTNOTE", tableName: "Preferences", value: "Disable all content blockers (under VPN settings) to activate this setting.", - comment: "Foot note displayed when custom DNS cannot be enabled, because content blockers should be disabled first." + comment: """ + Foot note displayed when custom DNS cannot be enabled, because content blockers should be \ + disabled first. + """ ), attributes: [.font: preferredFont] ) diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift index 28aed41d7709..b1bb49ccb2b8 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportInteractor.swift @@ -17,9 +17,6 @@ final class ProblemReportInteractor { private lazy var consolidatedLog: ConsolidatedApplicationLog = { let securityGroupIdentifier = ApplicationConfiguration.securityGroupIdentifier - - // TODO: make sure we redact old tokens - let redactStrings = [tunnelManager.deviceState.accountData?.number].compactMap { $0 } let report = ConsolidatedApplicationLog( diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController.swift index 93cfbde3eb5e..20b29e336425 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController.swift @@ -43,7 +43,10 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { textLabel.text = NSLocalizedString( "SUBHEAD_LABEL", tableName: "ProblemReport", - value: "To help you more effectively, your app’s log file will be attached to this message. Your data will remain secure and private, as it is anonymised before being sent over an encrypted channel.", + value: """ + To help you more effectively, your app’s log file will be attached to this message. \ + Your data will remain secure and private, as it is anonymised before being sent over an encrypted channel. + """, comment: "" ) return textLabel @@ -82,7 +85,10 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { textView.placeholder = NSLocalizedString( "DESCRIPTION_TEXTVIEW_PLACEHOLDER", tableName: "ProblemReport", - value: "To assist you better, please write in English or Swedish and include which country you are connecting from.", + value: """ + To assist you better, please write in English or Swedish and include \ + which country you are connecting from. + """, comment: "" ) textView.contentInsetAdjustmentBehavior = .never @@ -453,14 +459,14 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { self.messageTextView.roundCorners = false self.view.layoutIfNeeded() - }) { _ in + }, completion: { _ in self.isMessageTextViewExpanded = true self.textViewKeyboardResponder?.updateContentInsets() // Tell accessibility engine to scan the new layout UIAccessibility.post(notification: .layoutChanged, argument: nil) - } + }) } else { // Re-enable the large title @@ -476,7 +482,7 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { self.messageTextView.roundCorners = true self.view.layoutIfNeeded() - }) { _ in + }, completion: { _ in // Revert the content adjustment behavior self.messageTextView.contentInsetAdjustmentBehavior = .never @@ -487,7 +493,7 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { // Tell accessibility engine to scan the new layout UIAccessibility.post(notification: .layoutChanged, argument: nil) - } + }) } } @@ -504,7 +510,10 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { let message = NSLocalizedString( "EMPTY_EMAIL_ALERT_MESSAGE", tableName: "ProblemReport", - value: "You are about to send the problem report without a way for us to get back to you. If you want an answer to your report you will have to enter an email address.", + value: """ + You are about to send the problem report without a way for us to get back to you. \ + If you want an answer to your report you will have to enter an email address. + """, comment: "" ) @@ -718,4 +727,6 @@ final class ProblemReportViewController: UIViewController, UITextFieldDelegate { messageTextView.becomeFirstResponder() return false } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift index 8f07d64f717c..3ee5e3245250 100644 --- a/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift +++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift @@ -518,4 +518,6 @@ private extension [RelayLocation] { locations.contains(location) }) } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift index 89a44fa2f1ba..cb63f1428d3d 100644 --- a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift +++ b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift @@ -114,11 +114,7 @@ class SelectLocationCell: UITableViewCell { collapseButton.accessibilityIdentifier = "CollapseButton" collapseButton.isAccessibilityElement = false collapseButton.tintColor = .white - collapseButton.addTarget( - self, - action: #selector(handleCollapseButton(_:)), - for: .touchUpInside - ) + collapseButton.addTarget(self, action: #selector(handleCollapseButton(_:)), for: .touchUpInside) [locationLabel, tickImageView, statusIndicator, collapseButton].forEach { subview in subview.translatesAutoresizingMaskIntoConstraints = false @@ -132,8 +128,7 @@ class SelectLocationCell: UITableViewCell { setLayoutMargins() NSLayoutConstraint.activate([ - tickImageView.leadingAnchor - .constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor), + tickImageView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor), tickImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), statusIndicator.widthAnchor.constraint(equalToConstant: kRelayIndicatorSize), @@ -148,8 +143,7 @@ class SelectLocationCell: UITableViewCell { locationLabel.trailingAnchor.constraint(lessThanOrEqualTo: collapseButton.leadingAnchor) .withPriority(.defaultHigh), locationLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor), - locationLabel.bottomAnchor - .constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor), + locationLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor), collapseButton.widthAnchor .constraint( diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift index a6333462ee22..7cd88c8e81fc 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift @@ -80,11 +80,7 @@ class SettingsCell: UITableViewCell { contentView.backgroundColor = .clear infoButton.isHidden = true - infoButton.addTarget( - self, - action: #selector(handleInfoButton(_:)), - for: .touchUpInside - ) + infoButton.addTarget(self, action: #selector(handleInfoButton(_:)), for: .touchUpInside) titleLabel.translatesAutoresizingMaskIntoConstraints = false titleLabel.font = UIFont.systemFont(ofSize: 17) diff --git a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift index 11423c91e0ac..ec4541dabf87 100644 --- a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift +++ b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift @@ -37,9 +37,11 @@ class TermsOfServiceContentView: UIView { "PRIVACY_NOTICE_BODY", tableName: "TermsOfService", value: """ - You have a right to privacy. That’s why we never store activity logs, don’t ask for personal information, and encourage anonymous payments. + You have a right to privacy. That’s why we never store activity logs, don’t ask for personal \ + information, and encourage anonymous payments. - In some situations, as outlined in our privacy policy, we might process personal data that you choose to send, for example if you email us. + In some situations, as outlined in our privacy policy, we might process personal data that you \ + choose to send, for example if you email us. We strongly believe in retaining as little data as possible because we want you to remain anonymous. """, diff --git a/ios/MullvadVPN/View controllers/Tunnel/ConnectionPanelView.swift b/ios/MullvadVPN/View controllers/Tunnel/ConnectionPanelView.swift index 30a0b7170ef7..65cae0c148a5 100644 --- a/ios/MullvadVPN/View controllers/Tunnel/ConnectionPanelView.swift +++ b/ios/MullvadVPN/View controllers/Tunnel/ConnectionPanelView.swift @@ -75,7 +75,7 @@ class ConnectionPanelView: UIView { inAddressRow.translatesAutoresizingMaskIntoConstraints = false outAddressRow.translatesAutoresizingMaskIntoConstraints = false - // TODO: Unhide it when we have out address + // Remove this line when we have out address outAddressRow.isHidden = true inAddressRow.title = NSLocalizedString( diff --git a/ios/MullvadVPN/View controllers/Tunnel/DisconnectSplitButton.swift b/ios/MullvadVPN/View controllers/Tunnel/DisconnectSplitButton.swift index 59e807cfa04e..8baa2eaac71c 100644 --- a/ios/MullvadVPN/View controllers/Tunnel/DisconnectSplitButton.swift +++ b/ios/MullvadVPN/View controllers/Tunnel/DisconnectSplitButton.swift @@ -11,12 +11,11 @@ import UIKit class DisconnectSplitButton: UIView { private var secondaryButtonSize: CGSize { - // TODO: make it less hardcoded switch traitCollection.userInterfaceIdiom { case .phone: - return CGSize(width: 42, height: 42) + return UIMetrics.DisconnectSplitButton.secondaryButtonPhone case .pad: - return CGSize(width: 52, height: 52) + return UIMetrics.DisconnectSplitButton.secondaryButtonPad default: return .zero } diff --git a/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift b/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift index 9c1103325d36..2c26c6a07ceb 100644 --- a/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift +++ b/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift @@ -649,4 +649,6 @@ private extension TunnelState { return [] } } + + // swiftlint:disable:next file_length } diff --git a/ios/MullvadVPN/Views/AppButton.swift b/ios/MullvadVPN/Views/AppButton.swift index 2fc3603e2212..48bbd20ac873 100644 --- a/ios/MullvadVPN/Views/AppButton.swift +++ b/ios/MullvadVPN/Views/AppButton.swift @@ -286,6 +286,7 @@ class CustomButton: UIButton { } } + // swiftlint:disable:next cyclomatic_complexity private func computeLayout(forContentRect contentRect: CGRect) -> (CGRect, CGRect) { var imageRect = super.imageRect(forContentRect: contentRect) var titleRect = super.titleRect(forContentRect: contentRect) diff --git a/ios/MullvadVPNTests/DeviceCheckOperationTests.swift b/ios/MullvadVPNTests/DeviceCheckOperationTests.swift index cefd20ae45b4..887194d3d9eb 100644 --- a/ios/MullvadVPNTests/DeviceCheckOperationTests.swift +++ b/ios/MullvadVPNTests/DeviceCheckOperationTests.swift @@ -567,4 +567,6 @@ private extension AccountVerdict { } return false } + + // swiftlint:disable:next file_length } diff --git a/ios/Operations/AsyncOperation.swift b/ios/Operations/AsyncOperation.swift index ea8edb24c485..638d6ff415eb 100644 --- a/ios/Operations/AsyncOperation.swift +++ b/ios/Operations/AsyncOperation.swift @@ -392,6 +392,8 @@ open class AsyncOperation: Operation { } } +extension AsyncOperation: OperationBlockObserverSupport {} + extension Operation { public func addDependencies(_ dependencies: [Operation]) { for dependency in dependencies { @@ -399,28 +401,3 @@ extension Operation { } } } - -public protocol OperationBlockObserverSupport {} -extension AsyncOperation: OperationBlockObserverSupport {} - -extension OperationBlockObserverSupport where Self: AsyncOperation { - /// Add observer responding to cancellation event. - public func onCancel(_ fn: @escaping (Self) -> Void) { - addBlockObserver(OperationBlockObserver(didCancel: fn)) - } - - /// Add observer responding to finish event. - public func onFinish(_ fn: @escaping (Self, Error?) -> Void) { - addBlockObserver(OperationBlockObserver(didFinish: fn)) - } - - /// Add observer responding to start event. - public func onStart(_ fn: @escaping (Self) -> Void) { - addBlockObserver(OperationBlockObserver(didStart: fn)) - } - - /// Add block-based observer. - public func addBlockObserver(_ observer: OperationBlockObserver) { - addObserver(observer) - } -} diff --git a/ios/Operations/OperationBlockObserverSupport.swift b/ios/Operations/OperationBlockObserverSupport.swift new file mode 100644 index 000000000000..196adee76321 --- /dev/null +++ b/ios/Operations/OperationBlockObserverSupport.swift @@ -0,0 +1,35 @@ +// +// OperationBlockObserverSupport.swift +// Operations +// +// Created by Jon Petersson on 2023-09-07. +// Copyright © 2023 Mullvad VPN AB. All rights reserved. +// + +import Foundation + +public protocol OperationBlockObserverSupport {} + +extension OperationBlockObserverSupport where Self: AsyncOperation { + /// Add observer responding to cancellation event. + public func onCancel(_ fn: @escaping (Self) -> Void) { + addBlockObserver(OperationBlockObserver(didCancel: fn)) + } + + /// Add observer responding to finish event. + public func onFinish(_ fn: @escaping (Self, Error?) -> Void) { + addBlockObserver(OperationBlockObserver(didFinish: fn)) + } + + /// Add observer responding to start event. + public func onStart(_ fn: @escaping (Self) -> Void) { + addBlockObserver(OperationBlockObserver(didStart: fn)) + } + + /// Add block-based observer. + public func addBlockObserver(_ observer: OperationBlockObserver) { + addObserver(observer) + } + + // swiftlint:disable:next file_length +} diff --git a/ios/PacketTunnel/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider.swift index f06f1c0b4e1c..61e308d13bf3 100644 --- a/ios/PacketTunnel/PacketTunnelProvider.swift +++ b/ios/PacketTunnel/PacketTunnelProvider.swift @@ -763,4 +763,6 @@ extension PacketTunnelErrorWrapper { return nil } } + + // swiftlint:disable:next file_length } diff --git a/ios/PacketTunnelCore/Pinger/Pinger.swift b/ios/PacketTunnelCore/Pinger/Pinger.swift index 8f220f38b66b..0d754f3cfade 100644 --- a/ios/PacketTunnelCore/Pinger/Pinger.swift +++ b/ios/PacketTunnelCore/Pinger/Pinger.swift @@ -408,4 +408,6 @@ private extension IPv4Header { var isIPv4Version: Bool { (versionAndHeaderLength & 0xF0) == 0x40 } + + // swiftlint:disable:next file_length } diff --git a/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift b/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift index fc116fd7e1f4..443ff5ddedd9 100644 --- a/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift +++ b/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift @@ -635,4 +635,6 @@ public final class TunnelMonitor: TunnelMonitorProtocol { return nil } } + + // swiftlint:disable:next file_length } diff --git a/ios/PacketTunnelCoreTests/TunnelMonitorTests.swift b/ios/PacketTunnelCoreTests/TunnelMonitorTests.swift index e85a50617c8d..4677b042ad37 100644 --- a/ios/PacketTunnelCoreTests/TunnelMonitorTests.swift +++ b/ios/PacketTunnelCoreTests/TunnelMonitorTests.swift @@ -118,7 +118,7 @@ final class TunnelMonitorTests: XCTestCase { } case .connectionEstablished: - XCTFail() + XCTFail("Connection should fail.") case .networkReachabilityChanged: break From 944c07ef95f33d8b5798cdb779a2138ec33c3cd2 Mon Sep 17 00:00:00 2001 From: Bug Magnet Date: Fri, 8 Sep 2023 09:03:12 +0200 Subject: [PATCH 2/2] Fix Superfluous Disable Command --- ios/Operations/OperationBlockObserverSupport.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/ios/Operations/OperationBlockObserverSupport.swift b/ios/Operations/OperationBlockObserverSupport.swift index 196adee76321..9f9855abffa8 100644 --- a/ios/Operations/OperationBlockObserverSupport.swift +++ b/ios/Operations/OperationBlockObserverSupport.swift @@ -30,6 +30,4 @@ extension OperationBlockObserverSupport where Self: AsyncOperation { public func addBlockObserver(_ observer: OperationBlockObserver) { addObserver(observer) } - - // swiftlint:disable:next file_length }