summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-08-03 17:54:33 +0200
committerAndrej Mihajlov <and@mullvad.net>2022-08-03 17:54:33 +0200
commit6194006e59fb3c90a61981a18160ba50dddf4d73 (patch)
treeb8f2815d7a21e8fa3deb8ff4d73172bcc25e675e
parentb8b1c60c39d63de76062ba2292512b310cb0ff73 (diff)
parent8f74ad954b034b50dce09e4e8d00249eb6bad065 (diff)
downloadmullvadvpn-6194006e59fb3c90a61981a18160ba50dddf4d73.tar.xz
mullvadvpn-6194006e59fb3c90a61981a18160ba50dddf4d73.zip
Merge branch 'format-source-code'
-rw-r--r--ios/MullvadVPN/AccountContentView.swift47
-rw-r--r--ios/MullvadVPN/AccountInputGroupView.swift86
-rw-r--r--ios/MullvadVPN/AccountTextField.swift22
-rw-r--r--ios/MullvadVPN/AccountTokenInput.swift54
-rw-r--r--ios/MullvadVPN/AccountViewController.swift110
-rw-r--r--ios/MullvadVPN/AddressCache/AddressCacheStore.swift32
-rw-r--r--ios/MullvadVPN/AddressCache/AddressCacheTracker.swift24
-rw-r--r--ios/MullvadVPN/AlertPresenter.swift23
-rw-r--r--ios/MullvadVPN/AnyIPAddress.swift18
-rw-r--r--ios/MullvadVPN/AppButton.swift38
-rw-r--r--ios/MullvadVPN/AppDelegate.swift51
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift69
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift7
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift7
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift2
-rw-r--r--ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift60
-rw-r--r--ios/MullvadVPN/AppStoreReceipt.swift22
-rw-r--r--ios/MullvadVPN/ApplicationConfiguration.swift13
-rw-r--r--ios/MullvadVPN/AutomaticKeyboardResponder.swift48
-rw-r--r--ios/MullvadVPN/Bundle+ProductVersion.swift17
-rw-r--r--ios/MullvadVPN/CharacterSet+IPAddress.swift1
-rw-r--r--ios/MullvadVPN/CodingErrors+ChainedError.swift8
-rw-r--r--ios/MullvadVPN/ConnectContentView.swift52
-rw-r--r--ios/MullvadVPN/ConnectViewController.swift119
-rw-r--r--ios/MullvadVPN/ConnectionPanelView.swift22
-rw-r--r--ios/MullvadVPN/ConsolidatedApplicationLog.swift86
-rw-r--r--ios/MullvadVPN/CustomDateComponentsFormatting.swift11
-rw-r--r--ios/MullvadVPN/CustomNavigationBar.swift37
-rw-r--r--ios/MullvadVPN/CustomNavigationController.swift36
-rw-r--r--ios/MullvadVPN/CustomSplitViewController.swift20
-rw-r--r--ios/MullvadVPN/CustomSwitch.swift7
-rw-r--r--ios/MullvadVPN/CustomSwitchContainer.swift5
-rw-r--r--ios/MullvadVPN/CustomTextField.swift3
-rw-r--r--ios/MullvadVPN/CustomTextView.swift24
-rw-r--r--ios/MullvadVPN/DNSSettings.swift27
-rw-r--r--ios/MullvadVPN/DataSourceSnapshot.swift83
-rw-r--r--ios/MullvadVPN/DeviceManagementContentView.swift12
-rw-r--r--ios/MullvadVPN/DeviceManagementInteractor.swift10
-rw-r--r--ios/MullvadVPN/DeviceManagementViewController.swift13
-rw-r--r--ios/MullvadVPN/DeviceRowView.swift2
-rw-r--r--ios/MullvadVPN/DisconnectSplitButton.swift17
-rw-r--r--ios/MullvadVPN/DisplayChainedError.swift23
-rw-r--r--ios/MullvadVPN/EmptyTableViewHeaderFooterView.swift7
-rw-r--r--ios/MullvadVPN/GeoJSON.swift21
-rw-r--r--ios/MullvadVPN/HeaderBarView.swift32
-rw-r--r--ios/MullvadVPN/IPAddress+Codable.swift10
-rw-r--r--ios/MullvadVPN/IPEndpoint.swift45
-rw-r--r--ios/MullvadVPN/InAppPurchaseButton.swift5
-rw-r--r--ios/MullvadVPN/IntentHandlers.swift11
-rw-r--r--ios/MullvadVPN/LaunchViewController.swift3
-rw-r--r--ios/MullvadVPN/Location.swift2
-rw-r--r--ios/MullvadVPN/LocationDataSource.swift169
-rw-r--r--ios/MullvadVPN/Logging/ChainedError+Logger.swift3
-rw-r--r--ios/MullvadVPN/Logging/CustomFormatLogHandler.swift28
-rw-r--r--ios/MullvadVPN/Logging/LogRotation.swift4
-rw-r--r--ios/MullvadVPN/Logging/Logging.swift22
-rw-r--r--ios/MullvadVPN/Logging/OSLogHandler.swift29
-rw-r--r--ios/MullvadVPN/Logging/TextFileOutputStream.swift48
-rw-r--r--ios/MullvadVPN/LoginContentView.swift83
-rw-r--r--ios/MullvadVPN/LoginViewController.swift79
-rw-r--r--ios/MullvadVPN/NEProviderStopReason+Debug.swift37
-rw-r--r--ios/MullvadVPN/NEVPNStatus+Debug.swift4
-rw-r--r--ios/MullvadVPN/NSAttributedString+Markdown.swift3
-rw-r--r--ios/MullvadVPN/NotificationBannerView.swift22
-rw-r--r--ios/MullvadVPN/NotificationController.swift16
-rw-r--r--ios/MullvadVPN/NotificationManager.swift97
-rw-r--r--ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift41
-rw-r--r--ios/MullvadVPN/Notifications/TunnelErrorNotificationProvider.swift9
-rw-r--r--ios/MullvadVPN/ObserverList.swift2
-rw-r--r--ios/MullvadVPN/Operations/AsyncBlockOperation.swift1
-rw-r--r--ios/MullvadVPN/Operations/AsyncOperation.swift29
-rw-r--r--ios/MullvadVPN/Operations/AsyncOperationQueue.swift1
-rw-r--r--ios/MullvadVPN/Operations/BackgroundObserver.swift65
-rw-r--r--ios/MullvadVPN/Operations/InputInjectionBuilder.swift2
-rw-r--r--ios/MullvadVPN/Operations/OperationCompletion.swift53
-rw-r--r--ios/MullvadVPN/Operations/OperationCondition.swift2
-rw-r--r--ios/MullvadVPN/Operations/OperationObserver.swift3
-rw-r--r--ios/MullvadVPN/Operations/PresentAlertOperation.swift16
-rw-r--r--ios/MullvadVPN/Operations/ProductsRequestOperation.swift6
-rw-r--r--ios/MullvadVPN/Operations/ResultBlockOperation.swift14
-rw-r--r--ios/MullvadVPN/Operations/ResultOperation.swift3
-rw-r--r--ios/MullvadVPN/Operations/TransformOperation.swift11
-rw-r--r--ios/MullvadVPN/PreferencesDataSource.swift135
-rw-r--r--ios/MullvadVPN/PreferencesDataSourceDelegate.swift5
-rw-r--r--ios/MullvadVPN/PreferencesViewController.swift19
-rw-r--r--ios/MullvadVPN/PreferencesViewModel.swift5
-rw-r--r--ios/MullvadVPN/ProblemReportReviewViewController.swift9
-rw-r--r--ios/MullvadVPN/ProblemReportSubmissionOverlayView.swift38
-rw-r--r--ios/MullvadVPN/ProblemReportViewController.swift221
-rw-r--r--ios/MullvadVPN/REST/HTTP.swift4
-rw-r--r--ios/MullvadVPN/REST/RESTAPIProxy.swift126
-rw-r--r--ios/MullvadVPN/REST/RESTAccessTokenManager.swift17
-rw-r--r--ios/MullvadVPN/REST/RESTAccountsProxy.swift3
-rw-r--r--ios/MullvadVPN/REST/RESTAuthenticationProxy.swift3
-rw-r--r--ios/MullvadVPN/REST/RESTAuthorization.swift6
-rw-r--r--ios/MullvadVPN/REST/RESTDevicesProxy.swift72
-rw-r--r--ios/MullvadVPN/REST/RESTError.swift6
-rw-r--r--ios/MullvadVPN/REST/RESTNetworkOperation.swift60
-rw-r--r--ios/MullvadVPN/REST/RESTProxy.swift6
-rw-r--r--ios/MullvadVPN/REST/RESTRequestFactory.swift31
-rw-r--r--ios/MullvadVPN/REST/RESTResponseHandler.swift7
-rw-r--r--ios/MullvadVPN/REST/SSLPinningURLSessionDelegate.swift29
-rw-r--r--ios/MullvadVPN/RelayCache/CachedRelays.swift2
-rw-r--r--ios/MullvadVPN/RelayCache/RelayCacheIO.swift2
-rw-r--r--ios/MullvadVPN/RelayCache/RelayCacheTracker.swift17
-rw-r--r--ios/MullvadVPN/RelayConstraints.swift32
-rw-r--r--ios/MullvadVPN/RelaySelector.swift47
-rw-r--r--ios/MullvadVPN/Result+Extensions.swift8
-rw-r--r--ios/MullvadVPN/Result+UIBackgroundFetchResult.swift4
-rw-r--r--ios/MullvadVPN/RevokedDeviceViewController.swift11
-rw-r--r--ios/MullvadVPN/RootContainerViewController.swift136
-rw-r--r--ios/MullvadVPN/SKProduct+Formatting.swift2
-rw-r--r--ios/MullvadVPN/SceneDelegate.swift167
-rw-r--r--ios/MullvadVPN/SelectLocationCell.swift34
-rw-r--r--ios/MullvadVPN/SelectLocationHeaderView.swift4
-rw-r--r--ios/MullvadVPN/SelectLocationNavigationController.swift1
-rw-r--r--ios/MullvadVPN/SelectLocationViewController.swift93
-rw-r--r--ios/MullvadVPN/SettingsAccountCell.swift1
-rw-r--r--ios/MullvadVPN/SettingsAddDNSEntryCell.swift5
-rw-r--r--ios/MullvadVPN/SettingsCell.swift25
-rw-r--r--ios/MullvadVPN/SettingsDNSTextCell.swift12
-rw-r--r--ios/MullvadVPN/SettingsDataSource.swift55
-rw-r--r--ios/MullvadVPN/SettingsDataSourceDelegate.swift5
-rw-r--r--ios/MullvadVPN/SettingsManager/SettingsManager.swift24
-rw-r--r--ios/MullvadVPN/SettingsManager/TunnelSettingsV1.swift12
-rw-r--r--ios/MullvadVPN/SettingsManager/TunnelSettingsV2.swift12
-rw-r--r--ios/MullvadVPN/SettingsNavigationController.swift16
-rw-r--r--ios/MullvadVPN/SettingsStaticTextFooterView.swift8
-rw-r--r--ios/MullvadVPN/SettingsSwitchCell.swift11
-rw-r--r--ios/MullvadVPN/SettingsViewController.swift21
-rw-r--r--ios/MullvadVPN/SimulatorTunnelProvider.swift540
-rw-r--r--ios/MullvadVPN/SimulatorTunnelProviderHost.swift151
-rw-r--r--ios/MullvadVPN/SpinnerActivityIndicatorView.swift5
-rw-r--r--ios/MullvadVPN/StatusImageView.swift4
-rw-r--r--ios/MullvadVPN/String+Split.swift1
-rw-r--r--ios/MullvadVPN/Swizzle.swift14
-rw-r--r--ios/MullvadVPN/TermsOfServiceContentView.swift38
-rw-r--r--ios/MullvadVPN/TermsOfServiceViewController.swift22
-rw-r--r--ios/MullvadVPN/TranslucentButtonBlurView.swift14
-rw-r--r--ios/MullvadVPN/TunnelManager/LoadTunnelConfigurationOperation.swift3
-rw-r--r--ios/MullvadVPN/TunnelManager/LoadTunnelOperation.swift115
-rw-r--r--ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift10
-rw-r--r--ios/MullvadVPN/TunnelManager/MigrateSettingsOperation.swift27
-rw-r--r--ios/MullvadVPN/TunnelManager/PacketTunnelOptions.swift1
-rw-r--r--ios/MullvadVPN/TunnelManager/PacketTunnelStatus.swift2
-rw-r--r--ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift5
-rw-r--r--ios/MullvadVPN/TunnelManager/RegenerateTunnelPrivateKeyOperation.swift47
-rw-r--r--ios/MullvadVPN/TunnelManager/RotateKeyOperation.swift10
-rw-r--r--ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift7
-rw-r--r--ios/MullvadVPN/TunnelManager/SetAccountOperation.swift18
-rw-r--r--ios/MullvadVPN/TunnelManager/SetTunnelSettingsOperation.swift20
-rw-r--r--ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift22
-rw-r--r--ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift5
-rw-r--r--ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift3
-rw-r--r--ios/MullvadVPN/TunnelManager/Tunnel.swift11
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelInteractor.swift1
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManager.swift102
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManagerState.swift2
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelState.swift13
-rw-r--r--ios/MullvadVPN/TunnelManager/UpdateAccountDataOperation.swift5
-rw-r--r--ios/MullvadVPN/TunnelManager/UpdateDeviceDataOperation.swift9
-rw-r--r--ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift39
-rw-r--r--ios/MullvadVPN/UIColor+Helpers.swift12
-rw-r--r--ios/MullvadVPN/UIColor+Palette.swift1
-rw-r--r--ios/MullvadVPN/UIFont+Monospaced.swift4
-rw-r--r--ios/MullvadVPN/UIImage+TintColor.swift2
-rw-r--r--ios/MullvadVPN/UIMetrics.swift16
-rw-r--r--ios/MullvadVPN/UserInterfaceInteractionRestriction.swift3
-rw-r--r--ios/MullvadVPN/WireguardKeysContentView.swift32
-rw-r--r--ios/MullvadVPN/WireguardKeysViewController.swift61
-rw-r--r--ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift1
-rw-r--r--ios/MullvadVPNTests/AccountTokenInputTests.swift17
-rw-r--r--ios/MullvadVPNTests/CustomDateComponentsFormattingTests.swift6
-rw-r--r--ios/MullvadVPNTests/DataSourceSnapshotTests.swift12
-rw-r--r--ios/MullvadVPNTests/OperationConditionTests.swift3
-rw-r--r--ios/MullvadVPNTests/OperationInputInjectionTests.swift2
-rw-r--r--ios/MullvadVPNTests/OperationObserverTests.swift2
-rw-r--r--ios/MullvadVPNTests/OperationSmokeTests.swift4
-rw-r--r--ios/MullvadVPNTests/RelaySelectorTests.swift11
-rw-r--r--ios/MullvadVPNTests/StringTests.swift2
-rw-r--r--ios/PacketTunnel/PacketTunnelConfiguration.swift6
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider.swift40
-rw-r--r--ios/PacketTunnel/TunnelMonitor/Pinger.swift29
-rw-r--r--ios/PacketTunnel/TunnelMonitor/TunnelMonitor.swift33
-rw-r--r--ios/PacketTunnel/WireGuardAdapterError+Localization.swift4
-rw-r--r--ios/PacketTunnel/WireGuardLogLevel+Logging.swift2
186 files changed, 3401 insertions, 2145 deletions
diff --git a/ios/MullvadVPN/AccountContentView.swift b/ios/MullvadVPN/AccountContentView.swift
index b357f3d067..b0ff256dbc 100644
--- a/ios/MullvadVPN/AccountContentView.swift
+++ b/ios/MullvadVPN/AccountContentView.swift
@@ -9,7 +9,6 @@
import UIKit
class AccountContentView: UIView {
-
let purchaseButton: InAppPurchaseButton = {
let button = InAppPurchaseButton()
button.translatesAutoresizingMaskIntoConstraints = false
@@ -60,7 +59,12 @@ class AccountContentView: UIView {
}()
lazy var contentStackView: UIStackView = {
- let stackView = UIStackView(arrangedSubviews: [accountDeviceRow, accountTokenRowView, accountExpiryRowView])
+ let stackView =
+ UIStackView(arrangedSubviews: [
+ accountDeviceRow,
+ accountTokenRowView,
+ accountExpiryRowView,
+ ])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = UIMetrics.sectionSpacing
@@ -68,7 +72,8 @@ class AccountContentView: UIView {
}()
lazy var buttonStackView: UIStackView = {
- let stackView = UIStackView(arrangedSubviews: [purchaseButton, restorePurchasesButton, logoutButton])
+ let stackView =
+ UIStackView(arrangedSubviews: [purchaseButton, restorePurchasesButton, logoutButton])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = UIMetrics.interButtonSpacing
@@ -89,10 +94,13 @@ class AccountContentView: UIView {
contentStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
contentStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonStackView.topAnchor.constraint(greaterThanOrEqualTo: contentStackView.bottomAnchor, constant: UIMetrics.sectionSpacing),
+ buttonStackView.topAnchor.constraint(
+ greaterThanOrEqualTo: contentStackView.bottomAnchor,
+ constant: UIMetrics.sectionSpacing
+ ),
buttonStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
buttonStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
])
}
@@ -102,7 +110,6 @@ class AccountContentView: UIView {
}
class AccountDeviceRow: UIView {
-
var deviceName: String? {
didSet {
deviceLabel.text = deviceName?.capitalized ?? ""
@@ -146,7 +153,7 @@ class AccountDeviceRow: UIView {
deviceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8),
deviceLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
deviceLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
- deviceLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
+ deviceLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
])
isAccessibilityElement = true
@@ -237,7 +244,10 @@ class AccountNumberRow: UIView {
copyButton.heightAnchor.constraint(equalTo: accountNumberLabel.heightAnchor),
copyButton.centerYAnchor.constraint(equalTo: accountNumberLabel.centerYAnchor),
- copyButton.leadingAnchor.constraint(equalTo: showHideButton.trailingAnchor, constant: 24),
+ copyButton.leadingAnchor.constraint(
+ equalTo: showHideButton.trailingAnchor,
+ constant: 24
+ ),
copyButton.trailingAnchor.constraint(equalTo: trailingAnchor),
])
@@ -298,7 +308,6 @@ class AccountNumberRow: UIView {
}
}
-
private var _accessibilityAttributedValue: NSAttributedString? {
guard let accountNumber = accountNumber else {
return nil
@@ -330,7 +339,7 @@ class AccountNumberRow: UIView {
UIAccessibilityCustomAction(
name: showHideAccessibilityActionName,
target: self,
- selector: #selector(didTapShowHideAccount)
+ selector: #selector(didTapShowHideAccount)
),
UIAccessibilityCustomAction(
name: NSLocalizedString(
@@ -340,8 +349,8 @@ class AccountNumberRow: UIView {
comment: ""
),
target: self,
- selector: #selector(didTapCopyAccountNumber)
- )
+ selector: #selector(didTapCopyAccountNumber)
+ ),
]
}
@@ -368,12 +377,12 @@ class AccountNumberRow: UIView {
let tickIcon = UIImage(named: "IconTick")
copyButton.setImage(tickIcon, for: .normal)
- copyButton.tintColor = .successColor
+ copyButton.tintColor = .successColor
} else {
let copyIcon = UIImage(named: "IconCopy")
copyButton.setImage(copyIcon, for: .normal)
- copyButton.tintColor = .white
+ copyButton.tintColor = .white
}
}
@@ -405,12 +414,11 @@ class AccountNumberRow: UIView {
}
class AccountExpiryRow: UIView {
-
var value: Date? {
didSet {
let expiry = value
- if let expiry = expiry, expiry <= Date() {
+ if let expiry = expiry, expiry <= Date() {
let localizedString = NSLocalizedString(
"ACCOUNT_OUT_OF_TIME_LABEL",
tableName: "Account",
@@ -480,7 +488,10 @@ class AccountExpiryRow: UIView {
NSLayoutConstraint.activate([
textLabel.topAnchor.constraint(equalTo: topAnchor),
textLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
- textLabel.trailingAnchor.constraint(greaterThanOrEqualTo: activityIndicator.leadingAnchor, constant: -8),
+ textLabel.trailingAnchor.constraint(
+ greaterThanOrEqualTo: activityIndicator.leadingAnchor,
+ constant: -8
+ ),
activityIndicator.topAnchor.constraint(equalTo: textLabel.topAnchor),
activityIndicator.bottomAnchor.constraint(equalTo: textLabel.bottomAnchor),
@@ -489,7 +500,7 @@ class AccountExpiryRow: UIView {
valueLabel.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 8),
valueLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
valueLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
- valueLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
+ valueLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
])
isAccessibilityElement = true
diff --git a/ios/MullvadVPN/AccountInputGroupView.swift b/ios/MullvadVPN/AccountInputGroupView.swift
index 71b7a6a52f..39ece2f367 100644
--- a/ios/MullvadVPN/AccountInputGroupView.swift
+++ b/ios/MullvadVPN/AccountInputGroupView.swift
@@ -6,8 +6,8 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
private let accountInputGroupViewAnimationDuration: TimeInterval = 0.25
@@ -17,7 +17,6 @@ protocol AccountInputGroupViewDelegate: AnyObject {
}
class AccountInputGroupView: UIView {
-
enum Style {
case normal, error, authenticating
}
@@ -95,7 +94,7 @@ class AccountInputGroupView: UIView {
return view
}()
- private var showsLastUsedAccountRow: Bool = false
+ private var showsLastUsedAccountRow = false
private let lastUsedAccountButton: UIButton = {
let button = UIButton(type: .system)
@@ -147,8 +146,8 @@ class AccountInputGroupView: UIView {
switch loginState {
case .default:
return privateTextField.isEditing
- ? UIColor.AccountTextField.NormalState.borderColor
- : UIColor.clear
+ ? UIColor.AccountTextField.NormalState.borderColor
+ : UIColor.clear
case .failure:
return UIColor.AccountTextField.ErrorState.borderColor
@@ -208,9 +207,13 @@ class AccountInputGroupView: UIView {
sendButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
lastUsedAccountButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
- removeLastUsedAccountButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
+ removeLastUsedAccountButton.setContentCompressionResistancePriority(
+ .defaultHigh,
+ for: .horizontal
+ )
- lastUsedAccountVisibleConstraint = heightAnchor.constraint(equalTo: contentView.heightAnchor)
+ lastUsedAccountVisibleConstraint = heightAnchor
+ .constraint(equalTo: contentView.heightAnchor)
lastUsedAccountHiddenConstraint = heightAnchor.constraint(equalTo: topRowView.heightAnchor)
NSLayoutConstraint.activate([
@@ -248,11 +251,14 @@ class AccountInputGroupView: UIView {
lastUsedAccountButton.topAnchor.constraint(equalTo: bottomRowView.topAnchor),
lastUsedAccountButton.bottomAnchor.constraint(equalTo: bottomRowView.bottomAnchor),
lastUsedAccountButton.leadingAnchor.constraint(equalTo: bottomRowView.leadingAnchor),
- lastUsedAccountButton.trailingAnchor.constraint(equalTo: removeLastUsedAccountButton.leadingAnchor),
+ lastUsedAccountButton.trailingAnchor
+ .constraint(equalTo: removeLastUsedAccountButton.leadingAnchor),
removeLastUsedAccountButton.topAnchor.constraint(equalTo: bottomRowView.topAnchor),
- removeLastUsedAccountButton.bottomAnchor.constraint(equalTo: bottomRowView.bottomAnchor),
- removeLastUsedAccountButton.trailingAnchor.constraint(equalTo: bottomRowView.trailingAnchor),
+ removeLastUsedAccountButton.bottomAnchor
+ .constraint(equalTo: bottomRowView.bottomAnchor),
+ removeLastUsedAccountButton.trailingAnchor
+ .constraint(equalTo: bottomRowView.trailingAnchor),
removeLastUsedAccountButton.widthAnchor.constraint(equalTo: sendButton.widthAnchor),
])
@@ -268,9 +274,17 @@ class AccountInputGroupView: UIView {
updateSendButtonAppearance(animated: false)
updateKeyboardReturnKeyEnabled()
- lastUsedAccountButton.addTarget(self, action: #selector(didTapLastUsedAccount), for: .touchUpInside)
+ lastUsedAccountButton.addTarget(
+ self,
+ action: #selector(didTapLastUsedAccount),
+ for: .touchUpInside
+ )
- removeLastUsedAccountButton.addTarget(self, action: #selector(didTapRemoveLastUsedAccount), for: .touchUpInside)
+ removeLastUsedAccountButton.addTarget(
+ self,
+ action: #selector(didTapRemoveLastUsedAccount),
+ for: .touchUpInside
+ )
addTextFieldNotificationObservers()
addAccessibilityNotificationObservers()
@@ -403,18 +417,24 @@ class AccountInputGroupView: UIView {
private func addTextFieldNotificationObservers() {
let notificationCenter = NotificationCenter.default
- notificationCenter.addObserver(self,
- selector: #selector(textDidBeginEditing),
- name: UITextField.textDidBeginEditingNotification,
- object: privateTextField)
- notificationCenter.addObserver(self,
- selector: #selector(textDidChange),
- name: UITextField.textDidChangeNotification,
- object: privateTextField)
- notificationCenter.addObserver(self,
- selector: #selector(textDidEndEditing),
- name: UITextField.textDidEndEditingNotification,
- object: privateTextField)
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(textDidBeginEditing),
+ name: UITextField.textDidBeginEditingNotification,
+ object: privateTextField
+ )
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(textDidChange),
+ name: UITextField.textDidChangeNotification,
+ object: privateTextField
+ )
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(textDidEndEditing),
+ name: UITextField.textDidEndEditingNotification,
+ object: privateTextField
+ )
}
private func updateAppearance() {
@@ -485,7 +505,8 @@ class AccountInputGroupView: UIView {
bottomRowView.accessibilityElementsHidden = !shouldShow
if lastUsedAccountButton.accessibilityElementIsFocused() ||
- removeLastUsedAccountButton.accessibilityElementIsFocused() {
+ removeLastUsedAccountButton.accessibilityElementIsFocused()
+ {
UIAccessibility.post(notification: .layoutChanged, argument: textField)
}
}
@@ -529,7 +550,10 @@ class AccountInputGroupView: UIView {
}
private func borderBezierPath(size: CGSize) -> UIBezierPath {
- let borderPath = UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: borderRadius)
+ let borderPath = UIBezierPath(
+ roundedRect: CGRect(origin: .zero, size: size),
+ cornerRadius: borderRadius
+ )
borderPath.lineWidth = borderWidth
return borderPath
@@ -537,7 +561,7 @@ class AccountInputGroupView: UIView {
private func backgroundMaskImage(borderPath: UIBezierPath) -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: borderPath.bounds)
- return renderer.image { (ctx) in
+ return renderer.image { ctx in
borderPath.fill()
// strip out any overlapping pixels between the border and the background
@@ -548,13 +572,17 @@ class AccountInputGroupView: UIView {
// MARK: - Accessibility
private func addAccessibilityNotificationObservers() {
- NotificationCenter.default.addObserver(self, selector: #selector(voiceOverStatusDidChange(_:)), name: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil)
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(voiceOverStatusDidChange(_:)),
+ name: UIAccessibility.voiceOverStatusDidChangeNotification,
+ object: nil
+ )
}
@objc private func voiceOverStatusDidChange(_ notification: Notification) {
updateSendButtonAppearance(animated: true)
}
-
}
private class AccountInputBorderLayer: CAShapeLayer {
diff --git a/ios/MullvadVPN/AccountTextField.swift b/ios/MullvadVPN/AccountTextField.swift
index 8a4016ed73..74c6c1c45e 100644
--- a/ios/MullvadVPN/AccountTextField.swift
+++ b/ios/MullvadVPN/AccountTextField.swift
@@ -9,7 +9,6 @@
import UIKit
class AccountTextField: CustomTextField, UITextFieldDelegate {
-
private let input = AccountTokenInput()
var onReturnKey: ((AccountTextField) -> Bool)?
@@ -49,7 +48,7 @@ class AccountTextField: CustomTextField, UITextFieldDelegate {
return input.parsedString
}
- var enableReturnKey: Bool = true {
+ var enableReturnKey = true {
didSet {
updateKeyboardReturnKey()
}
@@ -66,8 +65,16 @@ class AccountTextField: CustomTextField, UITextFieldDelegate {
// MARK: - UITextFieldDelegate
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
- return input.textField(textField, shouldChangeCharactersIn: range, replacementString: string)
+ func textField(
+ _ textField: UITextField,
+ shouldChangeCharactersIn range: NSRange,
+ replacementString string: String
+ ) -> Bool {
+ return input.textField(
+ textField,
+ shouldChangeCharactersIn: range,
+ replacementString: string
+ )
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
@@ -77,7 +84,7 @@ class AccountTextField: CustomTextField, UITextFieldDelegate {
// MARK: - Notifications
@objc private func keyboardWillShow(_ notification: Notification) {
- if self.isFirstResponder {
+ if isFirstResponder {
updateKeyboardReturnKey()
}
}
@@ -90,7 +97,7 @@ class AccountTextField: CustomTextField, UITextFieldDelegate {
private func setEnableKeyboardReturnKey(_ enableReturnKey: Bool) {
let selector = NSSelectorFromString("setReturnKeyEnabled:")
- if let inputDelegate = self.inputDelegate as? NSObject, inputDelegate.responds(to: selector) {
+ if let inputDelegate = inputDelegate as? NSObject, inputDelegate.responds(to: selector) {
inputDelegate.setValue(enableReturnKey, forKey: "returnKeyEnabled")
}
}
@@ -102,12 +109,11 @@ class AccountTextField: CustomTextField, UITextFieldDelegate {
super.accessibilityValue = newValue
}
get {
- if self.text?.isEmpty ?? true {
+ if text?.isEmpty ?? true {
return ""
} else {
return super.accessibilityValue
}
}
}
-
}
diff --git a/ios/MullvadVPN/AccountTokenInput.swift b/ios/MullvadVPN/AccountTokenInput.swift
index 317f7717a9..cccc5a1a75 100644
--- a/ios/MullvadVPN/AccountTokenInput.swift
+++ b/ios/MullvadVPN/AccountTokenInput.swift
@@ -11,8 +11,7 @@ import UIKit
/// A class describing the account token input and caret management.
/// Suitable to be used with `UITextField`.
-class AccountTokenInput: NSObject
-{
+class AccountTokenInput: NSObject {
/// The group separator character
static let groupSeparator: Character = " "
@@ -41,7 +40,8 @@ class AccountTokenInput: NSObject
replaceCharacters(
in: stringRange,
replacementString: replacementString,
- emptySelection: false)
+ emptySelection: false
+ )
}
/// Replace characters in range maintaining the caret position
@@ -52,15 +52,16 @@ class AccountTokenInput: NSObject
/// This is normally the default state unless a text range is
/// selected.
///
- func replaceCharacters(in range: Range<String.Index>,
- replacementString: String,
- emptySelection: Bool)
- {
+ func replaceCharacters(
+ in range: Range<String.Index>,
+ replacementString: String,
+ emptySelection: Bool
+ ) {
var stringRange = range
// 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 { Self.isDigit($0) } ?? formattedString.startIndex
@@ -69,8 +70,10 @@ class AccountTokenInput: NSObject
}
// 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
@@ -102,7 +105,7 @@ class AccountTokenInput: NSObject
}
// Add separator between the groups of digits
- if numDigits > 0 && numDigits % Self.groupSize == 0 {
+ if numDigits > 0, numDigits % Self.groupSize == 0 {
reformattedString.append(Self.groupSeparator)
if originalCaretPosition > index {
@@ -124,17 +127,15 @@ class AccountTokenInput: NSObject
private class func isDigit(_ character: Character) -> Bool {
switch character {
- case "0"..."9":
+ case "0" ... "9":
return true
default:
return false
}
}
-
}
extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
-
/// Update the text and caret position in the given text field
func updateTextField(_ textField: UITextField) {
updateTextField(textField, notifyDelegate: false)
@@ -142,14 +143,19 @@ extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
// MARK: - UITextFieldDelegate
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
+ func textField(
+ _ textField: UITextField,
+ shouldChangeCharactersIn range: NSRange,
+ replacementString string: String
+ ) -> Bool {
let emptySelection = textField.selectedTextRange?.isEmpty ?? false
let stringRange = Range(range, in: formattedString)!
replaceCharacters(
in: stringRange,
replacementString: string,
- emptySelection: emptySelection)
+ emptySelection: emptySelection
+ )
updateTextField(textField, notifyDelegate: true)
@@ -161,8 +167,8 @@ extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
func textPasteConfigurationSupporting(
_ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting,
performPasteOf attributedString: NSAttributedString,
- to textRange: UITextRange) -> UITextRange
- {
+ to textRange: UITextRange
+ ) -> UITextRange {
guard let textField = textPasteConfigurationSupporting as? UITextField else {
return textRange
}
@@ -176,7 +182,8 @@ extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
replaceCharacters(
in: stringRange,
replacementString: attributedString.string,
- emptySelection: textRange.isEmpty)
+ emptySelection: textRange.isEmpty
+ )
updateTextField(textField, notifyDelegate: true)
return caretTextRange(in: textField)!
@@ -196,7 +203,8 @@ extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
private func caretTextRange(in textField: UITextField) -> UITextRange? {
guard let position = textField.position(
from: textField.beginningOfDocument,
- offset: caretPositionUtf16) else { return nil }
+ offset: caretPositionUtf16
+ ) else { return nil }
return textField.textRange(from: position, to: position)
}
@@ -213,10 +221,10 @@ extension AccountTokenInput: UITextFieldDelegate, UITextPasteDelegate {
}
/// Post `UITextField.textDidChange` notification
- class private func notifyTextDidChange(in textField: UITextField) {
+ private class func notifyTextDidChange(in textField: UITextField) {
NotificationCenter.default.post(
name: UITextField.textDidChangeNotification,
- object: textField)
+ object: textField
+ )
}
}
-
diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift
index 579ca685fd..a755ef2239 100644
--- a/ios/MullvadVPN/AccountViewController.swift
+++ b/ios/MullvadVPN/AccountViewController.swift
@@ -6,9 +6,9 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
+import Logging
import StoreKit
import UIKit
-import Logging
protocol AccountViewControllerDelegate: AnyObject {
func accountViewControllerDidLogout(_ controller: AccountViewController)
@@ -29,21 +29,22 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
weak var delegate: AccountViewControllerDelegate?
private lazy var purchaseButtonInteractionRestriction =
- UserInterfaceInteractionRestriction { [weak self] (enableUserInteraction, _) in
+ UserInterfaceInteractionRestriction { [weak self] enableUserInteraction, _ in
// Make sure to disable the button if the product is not loaded
self?.contentView.purchaseButton.isEnabled = enableUserInteraction &&
self?.product != nil &&
AppStorePaymentManager.canMakePayments
- }
+ }
private lazy var viewControllerInteractionRestriction =
- UserInterfaceInteractionRestriction { [weak self] (enableUserInteraction, animated) in
+ UserInterfaceInteractionRestriction { [weak self] enableUserInteraction, animated in
self?.setEnableUserInteraction(enableUserInteraction, animated: true)
- }
+ }
private lazy var compoundInteractionRestriction =
CompoundUserInterfaceInteractionRestriction(restrictions: [
- purchaseButtonInteractionRestriction, viewControllerInteractionRestriction])
+ purchaseButtonInteractionRestriction, viewControllerInteractionRestriction,
+ ])
private var product: SKProduct?
@@ -70,7 +71,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
- contentView.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.bottomAnchor),
+ contentView.bottomAnchor
+ .constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
@@ -87,8 +89,16 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
self?.copyAccountToken()
}
- contentView.restorePurchasesButton.addTarget(self, action: #selector(restorePurchases), for: .touchUpInside)
- contentView.purchaseButton.addTarget(self, action: #selector(doPurchase), for: .touchUpInside)
+ contentView.restorePurchasesButton.addTarget(
+ self,
+ action: #selector(restorePurchases),
+ for: .touchUpInside
+ )
+ contentView.purchaseButton.addTarget(
+ self,
+ action: #selector(doPurchase),
+ for: .touchUpInside
+ )
contentView.logoutButton.addTarget(self, action: #selector(doLogout), for: .touchUpInside)
AppStorePaymentManager.shared.addPaymentObserver(self)
@@ -107,7 +117,7 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
// MARK: - Private methods
private func updateView(from deviceState: DeviceState?) {
- guard case .loggedIn(let accountData, let deviceData) = deviceState else {
+ guard case let .loggedIn(accountData, deviceData) = deviceState else {
return
}
@@ -124,25 +134,26 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
purchaseButtonInteractionRestriction.increase(animated: true)
- _ = AppStorePaymentManager.shared.requestProducts(with: [inAppPurchase]) { [weak self] completion in
- guard let self = self else { return }
+ _ = AppStorePaymentManager.shared
+ .requestProducts(with: [inAppPurchase]) { [weak self] completion in
+ guard let self = self else { return }
- switch completion {
- case .success(let response):
- if let product = response.products.first {
- self.setProduct(product, animated: true)
- }
+ switch completion {
+ case let .success(response):
+ if let product = response.products.first {
+ self.setProduct(product, animated: true)
+ }
- case .failure(let error):
- self.didFailLoadingProducts(with: error)
+ case let .failure(error):
+ self.didFailLoadingProducts(with: error)
- case .cancelled:
- break
- }
+ case .cancelled:
+ break
+ }
- self.contentView.purchaseButton.isLoading = false
- self.purchaseButtonInteractionRestriction.decrease(animated: true)
- }
+ self.contentView.purchaseButton.isLoading = false
+ self.purchaseButtonInteractionRestriction.decrease(animated: true)
+ }
}
private func setProduct(_ product: SKProduct, animated: Bool) {
@@ -187,7 +198,7 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
private func setEnableUserInteraction(_ enableUserInteraction: Bool, animated: Bool) {
// Disable all buttons
- [contentView.restorePurchasesButton, contentView.logoutButton].forEach { (button) in
+ [contentView.restorePurchasesButton, contentView.logoutButton].forEach { button in
button?.isEnabled = enableUserInteraction
}
@@ -214,8 +225,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
private func showTimeAddedConfirmationAlert(
with response: REST.CreateApplePaymentResponse,
- context: REST.CreateApplePaymentResponse.Context)
- {
+ context: REST.CreateApplePaymentResponse.Context
+ ) {
let alertController = UIAlertController(
title: response.alertTitle(context: context),
message: response.alertMessage(context: context),
@@ -262,9 +273,10 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
comment: ""
),
style: .cancel,
- handler: { (alertAction) in
+ handler: { alertAction in
completion(false)
- })
+ }
+ )
)
alertController.addAction(
@@ -276,9 +288,10 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
comment: ""
),
style: .destructive,
- handler: { (alertAction) in
+ handler: { alertAction in
completion(true)
- })
+ }
+ )
)
alertPresenter.enqueue(alertController, presentingController: self)
@@ -323,7 +336,10 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
@@ -333,7 +349,13 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
// MARK: - AppStorePaymentObserver
- func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction?, payment: SKPayment, accountToken: String?, didFailWithError error: AppStorePaymentManager.Error) {
+ func appStorePaymentManager(
+ _ manager: AppStorePaymentManager,
+ transaction: SKPaymentTransaction?,
+ payment: SKPayment,
+ accountToken: String?,
+ didFailWithError error: AppStorePaymentManager.Error
+ ) {
let alertController = UIAlertController(
title: NSLocalizedString(
"CANNOT_COMPLETE_PURCHASE_ALERT_TITLE",
@@ -352,7 +374,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
tableName: "Account",
value: "OK",
comment: ""
- ), style: .cancel)
+ ), style: .cancel
+ )
)
alertPresenter.enqueue(alertController, presentingController: self)
@@ -362,7 +385,12 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
}
}
- func appStorePaymentManager(_ manager: AppStorePaymentManager, transaction: SKPaymentTransaction, accountToken: String, didFinishWithResponse response: REST.CreateApplePaymentResponse) {
+ func appStorePaymentManager(
+ _ manager: AppStorePaymentManager,
+ transaction: SKPaymentTransaction,
+ accountToken: String,
+ didFinishWithResponse response: REST.CreateApplePaymentResponse
+ ) {
showTimeAddedConfirmationAlert(with: response, context: .purchase)
if transaction.payment == pendingPayment {
@@ -370,7 +398,6 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
}
}
-
// MARK: - Actions
@objc private func doLogout() {
@@ -391,7 +418,8 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
@objc private func doPurchase() {
guard let accountData = TunnelManager.shared.deviceState.accountData,
- let product = product else {
+ let product = product
+ else {
return
}
@@ -412,10 +440,10 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
_ = AppStorePaymentManager.shared.restorePurchases(for: accountData.number) { completion in
switch completion {
- case .success(let response):
+ case let .success(response):
self.showTimeAddedConfirmationAlert(with: response, context: .restoration)
- case .failure(let error):
+ case let .failure(error):
let alertController = UIAlertController(
title: NSLocalizedString(
"RESTORE_PURCHASES_FAILURE_ALERT_TITLE",
@@ -443,11 +471,9 @@ class AccountViewController: UIViewController, AppStorePaymentObserver, TunnelOb
self.compoundInteractionRestriction.decrease(animated: true)
}
}
-
}
private extension REST.CreateApplePaymentResponse {
-
enum Context {
case purchase
case restoration
diff --git a/ios/MullvadVPN/AddressCache/AddressCacheStore.swift b/ios/MullvadVPN/AddressCache/AddressCacheStore.swift
index 2addeb2754..94ea5d5850 100644
--- a/ios/MullvadVPN/AddressCache/AddressCacheStore.swift
+++ b/ios/MullvadVPN/AddressCache/AddressCacheStore.swift
@@ -10,7 +10,6 @@ import Foundation
import Logging
extension AddressCache {
-
struct CachedAddresses: Codable {
/// Date when the cached addresses were last updated.
var updatedAt: Date
@@ -50,12 +49,20 @@ extension AddressCache {
}
class Store {
-
static let shared: Store = {
let cacheFilename = "api-ip-address.json"
- let cacheDirectoryURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
- let cacheFileURL = cacheDirectoryURL.appendingPathComponent(cacheFilename, isDirectory: false)
- let prebundledCacheFileURL = Bundle.main.url(forResource: cacheFilename, withExtension: nil)!
+ let cacheDirectoryURL = FileManager.default.urls(
+ for: .applicationSupportDirectory,
+ in: .userDomainMask
+ ).first!
+ let cacheFileURL = cacheDirectoryURL.appendingPathComponent(
+ cacheFilename,
+ isDirectory: false
+ )
+ let prebundledCacheFileURL = Bundle.main.url(
+ forResource: cacheFilename,
+ withExtension: nil
+ )!
return Store(
cacheFileURL: cacheFileURL,
@@ -67,7 +74,7 @@ extension AddressCache {
return CachedAddresses(
updatedAt: Date(timeIntervalSince1970: 0),
endpoints: [
- ApplicationConfiguration.defaultAPIEndpoint
+ ApplicationConfiguration.defaultAPIEndpoint,
]
)
}
@@ -154,7 +161,10 @@ extension AddressCache {
currentEndpoint = cachedAddresses.endpoints.first!
- logger.debug("Failed to communicate using \(failedEndpoint). Next endpoint: \(currentEndpoint)")
+ logger
+ .debug(
+ "Failed to communicate using \(failedEndpoint). Next endpoint: \(currentEndpoint)"
+ )
do {
try writeToDisk()
@@ -216,8 +226,7 @@ extension AddressCache {
cacheFileURL: URL,
prebundledCacheFileURL: URL,
logger: Logger
- ) throws -> ReadResult
- {
+ ) throws -> ReadResult {
do {
let readResult = ReadResult(
cachedAddresses: try readFromCacheLocation(cacheFileURL),
@@ -265,7 +274,9 @@ extension AddressCache {
return try JSONDecoder().decode(CachedAddresses.self, from: data)
}
- private static func readFromBundle(_ prebundledCacheFileURL: URL) throws -> CachedAddresses {
+ private static func readFromBundle(_ prebundledCacheFileURL: URL) throws
+ -> CachedAddresses
+ {
let data = try Data(contentsOf: prebundledCacheFileURL)
let endpoints = try JSONDecoder().decode([AnyIPEndpoint].self, from: data)
@@ -287,6 +298,5 @@ extension AddressCache {
let data = try JSONEncoder().encode(cachedAddresses)
try data.write(to: cacheFileURL, options: .atomic)
}
-
}
}
diff --git a/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift b/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift
index 430212c24d..69300772ac 100644
--- a/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift
+++ b/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift
@@ -6,19 +6,16 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
extension AddressCache {
-
class Tracker {
/// Shared instance.
- static let shared: AddressCache.Tracker = {
- return AddressCache.Tracker(
- apiProxy: REST.ProxyFactory.shared.createAPIProxy(),
- store: AddressCache.Store.shared
- )
- }()
+ static let shared = AddressCache.Tracker(
+ apiProxy: REST.ProxyFactory.shared.createAPIProxy(),
+ store: AddressCache.Store.shared
+ )
/// Update interval (in seconds).
private static let updateInterval: TimeInterval = 60 * 60 * 24
@@ -95,8 +92,7 @@ extension AddressCache {
func updateEndpoints(
completionHandler: ((OperationCompletion<Bool, Error>) -> Void)? = nil
- ) -> Cancellable
- {
+ ) -> Cancellable {
let operation = ResultBlockOperation<Bool, Error> { operation in
guard self.nextScheduleDate() <= Date() else {
operation.finish(completion: .success(false))
@@ -142,10 +138,10 @@ extension AddressCache {
defer { nslock.unlock() }
switch completion {
- case .success(let endpoints):
+ case let .success(endpoints):
store.setEndpoints(endpoints)
- case .failure(let error):
+ case let .failure(error):
logger.error(
chainedError: AnyChainedError(error),
message: "Failed to update address cache."
@@ -180,7 +176,8 @@ extension AddressCache {
let scheduleDate = self._nextScheduleDate()
- self.logger.debug("Schedule next address cache update at \(scheduleDate.logFormatDate()).")
+ self.logger
+ .debug("Schedule next address cache update at \(scheduleDate.logFormatDate()).")
self.scheduleEndpointsUpdate(startTime: .now() + scheduleDate.timeIntervalSinceNow)
}
@@ -199,6 +196,5 @@ extension AddressCache {
return max(nextDate, Date())
}
-
}
}
diff --git a/ios/MullvadVPN/AlertPresenter.swift b/ios/MullvadVPN/AlertPresenter.swift
index f67b07a3e8..c260201e05 100644
--- a/ios/MullvadVPN/AlertPresenter.swift
+++ b/ios/MullvadVPN/AlertPresenter.swift
@@ -10,7 +10,8 @@ import Foundation
import UIKit
class AlertPresenter {
- static let alertControllerDidDismissNotification = Notification.Name("UIAlertControllerDidDismiss")
+ static let alertControllerDidDismissNotification = Notification
+ .Name("UIAlertControllerDidDismiss")
private let operationQueue: OperationQueue = {
let operationQueue = AsyncOperationQueue()
@@ -23,14 +24,22 @@ class AlertPresenter {
/// Swizzle `viewDidDisappear` on `UIAlertController` in order to be able to
/// detect when the controller disappears.
/// The event is broadcasted via `AlertPresenter.alertControllerDidDismissNotification` notification.
- swizzleMethod(aClass: UIAlertController.self, originalSelector: #selector(UIAlertController.viewDidDisappear(_:)), newSelector: #selector(UIAlertController.alertPresenter_viewDidDisappear(_:)))
+ swizzleMethod(
+ aClass: UIAlertController.self,
+ originalSelector: #selector(UIAlertController.viewDidDisappear(_:)),
+ newSelector: #selector(UIAlertController.alertPresenter_viewDidDisappear(_:))
+ )
}()
init() {
_ = Self.initClass
}
- func enqueue(_ alertController: UIAlertController, presentingController: UIViewController, presentCompletion: (() -> Void)? = nil) {
+ func enqueue(
+ _ alertController: UIAlertController,
+ presentingController: UIViewController,
+ presentCompletion: (() -> Void)? = nil
+ ) {
let operation = PresentAlertOperation(
alertController: alertController,
presentingController: presentingController,
@@ -43,16 +52,18 @@ class AlertPresenter {
func cancelAll() {
operationQueue.cancelAllOperations()
}
-
}
-fileprivate extension UIAlertController {
+private extension UIAlertController {
@objc dynamic func alertPresenter_viewDidDisappear(_ animated: Bool) {
// Call super implementation
alertPresenter_viewDidDisappear(animated)
if presentingViewController == nil {
- NotificationCenter.default.post(name: AlertPresenter.alertControllerDidDismissNotification, object: self)
+ NotificationCenter.default.post(
+ name: AlertPresenter.alertControllerDidDismissNotification,
+ object: self
+ )
}
}
}
diff --git a/ios/MullvadVPN/AnyIPAddress.swift b/ios/MullvadVPN/AnyIPAddress.swift
index 1898754a69..7916fe3a78 100644
--- a/ios/MullvadVPN/AnyIPAddress.swift
+++ b/ios/MullvadVPN/AnyIPAddress.swift
@@ -20,9 +20,9 @@ enum AnyIPAddress: IPAddress, Codable, Equatable, CustomDebugStringConvertible {
private var innerAddress: IPAddress {
switch self {
- case .ipv4(let ipv4Address):
+ case let .ipv4(ipv4Address):
return ipv4Address
- case .ipv6(let ipv6Address):
+ case let .ipv6(ipv6Address):
return ipv6Address
}
}
@@ -39,7 +39,11 @@ enum AnyIPAddress: IPAddress, Codable, Equatable, CustomDebugStringConvertible {
} else if container.contains(.ipv6) {
self = .ipv6(try container.decode(IPv6Address.self, forKey: .ipv6))
} else {
- throw DecodingError.dataCorruptedError(forKey: .ipv4, in: container, debugDescription: "Invalid AnyIPAddress representation")
+ throw DecodingError.dataCorruptedError(
+ forKey: .ipv4,
+ in: container,
+ debugDescription: "Invalid AnyIPAddress representation"
+ )
}
}
@@ -47,9 +51,9 @@ enum AnyIPAddress: IPAddress, Codable, Equatable, CustomDebugStringConvertible {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
- case .ipv4(let ipv4Address):
+ case let .ipv4(ipv4Address):
try container.encode(ipv4Address, forKey: .ipv4)
- case .ipv6(let ipv6Address):
+ case let .ipv6(ipv6Address):
try container.encode(ipv6Address, forKey: .ipv6)
}
}
@@ -92,9 +96,9 @@ enum AnyIPAddress: IPAddress, Codable, Equatable, CustomDebugStringConvertible {
var debugDescription: String {
switch self {
- case .ipv4(let ipv4Address):
+ case let .ipv4(ipv4Address):
return "\(ipv4Address)"
- case .ipv6(let ipv6Address):
+ case let .ipv6(ipv6Address):
return "\(ipv6Address)"
}
}
diff --git a/ios/MullvadVPN/AppButton.swift b/ios/MullvadVPN/AppButton.swift
index e6ff62a07f..7704fbe49f 100644
--- a/ios/MullvadVPN/AppButton.swift
+++ b/ios/MullvadVPN/AppButton.swift
@@ -51,7 +51,6 @@ private extension UIControl.State {
/// A subclass that implements the button that visually look like URL links on the web
class LinkButton: CustomButton {
-
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
@@ -77,15 +76,18 @@ class LinkButton: CustomButton {
private func updateAttributedTitle(string: String?) {
let states: [UIControl.State] = [.normal, .highlighted, .disabled]
- states.forEach { (state) in
+ states.forEach { state in
let attributedTitle = string.flatMap { makeAttributedTitle($0, for: state) }
self.setAttributedTitle(attributedTitle, for: state)
}
}
- private func makeAttributedTitle(_ title: String, for state: UIControl.State) -> NSAttributedString {
+ private func makeAttributedTitle(
+ _ title: String,
+ for state: UIControl.State
+ ) -> NSAttributedString {
var attributes: [NSAttributedString.Key: Any] = [
- .underlineStyle: NSUnderlineStyle.single.rawValue
+ .underlineStyle: NSUnderlineStyle.single.rawValue,
]
if let titleColor = state.customButtonTitleColor {
@@ -98,7 +100,6 @@ class LinkButton: CustomButton {
/// A subclass that implements action buttons used across the app
class AppButton: CustomButton {
-
var defaultContentInsets: UIEdgeInsets {
switch traitCollection.userInterfaceIdiom {
case .phone:
@@ -132,9 +133,11 @@ class AppButton: CustomButton {
case .translucentNeutral:
return UIImage(named: "TranslucentNeutralButton")
case .translucentDangerSplitLeft:
- return UIImage(named: "TranslucentDangerSplitLeftButton")?.imageFlippedForRightToLeftLayoutDirection()
+ return UIImage(named: "TranslucentDangerSplitLeftButton")?
+ .imageFlippedForRightToLeftLayoutDirection()
case .translucentDangerSplitRight:
- return UIImage(named: "TranslucentDangerSplitRightButton")?.imageFlippedForRightToLeftLayoutDirection()
+ return UIImage(named: "TranslucentDangerSplitRightButton")?
+ .imageFlippedForRightToLeftLayoutDirection()
}
}
}
@@ -167,19 +170,19 @@ class AppButton: CustomButton {
var contentInsets = contentEdgeInsets
if contentInsets.top == 0 {
- contentInsets.top = self.defaultContentInsets.top
+ contentInsets.top = defaultContentInsets.top
}
if contentInsets.bottom == 0 {
- contentInsets.bottom = self.defaultContentInsets.bottom
+ contentInsets.bottom = defaultContentInsets.bottom
}
if contentInsets.right == 0 {
- contentInsets.right = self.defaultContentInsets.right
+ contentInsets.right = defaultContentInsets.right
}
if contentInsets.left == 0 {
- contentInsets.left = self.defaultContentInsets.left
+ contentInsets.left = defaultContentInsets.left
}
contentEdgeInsets = contentInsets
@@ -188,7 +191,7 @@ class AppButton: CustomButton {
titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
let states: [UIControl.State] = [.normal, .highlighted, .disabled]
- states.forEach { (state) in
+ states.forEach { state in
if let titleColor = state.customButtonTitleColor {
setTitleColor(titleColor, for: state)
}
@@ -207,16 +210,16 @@ class AppButton: CustomButton {
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
- if traitCollection.userInterfaceIdiom != previousTraitCollection?.userInterfaceIdiom, !overrideContentEdgeInsets {
- contentEdgeInsets = self.defaultContentInsets
+ if traitCollection.userInterfaceIdiom != previousTraitCollection?.userInterfaceIdiom,
+ !overrideContentEdgeInsets
+ {
+ contentEdgeInsets = defaultContentInsets
}
}
-
}
/// A custom `UIButton` subclass that implements additional layouts for the image
class CustomButton: UIButton {
-
var imageAlignment: ButtonImageAlignment = .leading {
didSet {
invalidateIntrinsicContentSize()
@@ -292,7 +295,7 @@ class CustomButton: UIButton {
} 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 = self.imageRect(forContentRect: contentRect(forBounds: bounds))
+ let imageRect = imageRect(forContentRect: contentRect(forBounds: bounds))
if imageView?.frame != imageRect {
imageView?.frame = imageRect
}
@@ -368,5 +371,4 @@ class CustomButton: UIButton {
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
return computeLayout(forContentRect: contentRect).0
}
-
}
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 6908f86a43..39a669b3fd 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -6,19 +6,19 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import BackgroundTasks
-import StoreKit
-import UserNotifications
import Intents
import Logging
+import StoreKit
+import UIKit
+import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
private var logger: Logger!
#if targetEnvironment(simulator)
- private let simulatorTunnelProvider = SimulatorTunnelProviderHost()
+ private let simulatorTunnelProvider = SimulatorTunnelProviderHost()
#endif
private let operationQueue: AsyncOperationQueue = {
@@ -32,14 +32,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// MARK: - Application lifecycle
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
initLoggingSystem(bundleIdentifier: Bundle.main.bundleIdentifier!)
logger = Logger(label: "AppDelegate")
#if targetEnvironment(simulator)
- // Configure mock tunnel provider on simulator
- SimulatorTunnelProvider.shared.delegate = simulatorTunnelProvider
+ // Configure mock tunnel provider on simulator
+ SimulatorTunnelProvider.shared.delegate = simulatorTunnelProvider
#endif
if #available(iOS 13.0, *) {
@@ -96,9 +99,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
- performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
- )
- {
+ performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult)
+ -> Void
+ ) {
logger.debug("Start background refresh.")
let updateAddressCacheOperation = ResultBlockOperation<Bool, Error> { operation in
@@ -122,8 +125,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
}
- let rotatePrivateKeyOperation = ResultBlockOperation<Bool, Error>
- { operation in
+ let rotatePrivateKeyOperation = ResultBlockOperation<Bool, Error> { operation in
let handle = TunnelManager.shared.rotatePrivateKey(forceRotate: false) { completion in
operation.finish(completion: completion)
}
@@ -134,13 +136,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
rotatePrivateKeyOperation.addDependencies([
updateRelaysOperation,
- updateAddressCacheOperation
+ updateAddressCacheOperation,
])
let operations = [
updateAddressCacheOperation,
updateRelaysOperation,
- rotatePrivateKeyOperation
+ rotatePrivateKeyOperation,
]
let completeOperation = TransformOperation<UIBackgroundFetchResult, Void, Never>(
@@ -377,7 +379,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
private func setupNotificationHandler() {
NotificationManager.shared.notificationProviders = [
AccountExpiryNotificationProvider(),
- TunnelErrorNotificationProvider()
+ TunnelErrorNotificationProvider(),
]
UNUserNotificationCenter.current().delegate = self
}
@@ -389,8 +391,7 @@ extension AppDelegate: AppStorePaymentManagerDelegate {
func appStorePaymentManager(
_ manager: AppStorePaymentManager,
didRequestAccountTokenFor payment: SKPayment
- ) -> String?
- {
+ ) -> String? {
// Since we do not persist the relation between payment and account number between the
// app launches, we assume that all successful purchases belong to the active account
// number.
@@ -401,10 +402,15 @@ extension AppDelegate: AppStorePaymentManagerDelegate {
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
- func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
+ func userNotificationCenter(
+ _ center: UNUserNotificationCenter,
+ didReceive response: UNNotificationResponse,
+ withCompletionHandler completionHandler: @escaping () -> Void
+ ) {
let blockOperation = AsyncBlockOperation(dispatchQueue: .main) {
if response.notification.request.identifier == accountExpiryNotificationIdentifier,
- response.actionIdentifier == UNNotificationDefaultActionIdentifier {
+ response.actionIdentifier == UNNotificationDefaultActionIdentifier
+ {
if #available(iOS 13.0, *) {
let sceneDelegate = UIApplication.shared.connectedScenes
.first?.delegate as? SceneDelegate
@@ -421,7 +427,12 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
operationQueue.addOperation(blockOperation)
}
- func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
+ func userNotificationCenter(
+ _ center: UNUserNotificationCenter,
+ willPresent notification: UNNotification,
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions)
+ -> Void
+ ) {
if #available(iOS 14.0, *) {
completionHandler([.list])
} else {
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift
index 6b581edf84..ffeba9c84c 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManager.swift
@@ -7,11 +7,10 @@
//
import Foundation
-import StoreKit
import Logging
+import StoreKit
class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
-
private enum OperationCategory {
static let sendAppStoreReceipt = "AppStorePaymentManager.sendAppStoreReceipt"
static let productsRequest = "AppStorePaymentManager.productsRequest"
@@ -75,7 +74,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
// MARK: - SKPaymentTransactionObserver
- func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
+ func paymentQueue(
+ _ queue: SKPaymentQueue,
+ updatedTransactions transactions: [SKPaymentTransaction]
+ ) {
// Ensure that all calls happen on main queue
if Thread.isMainThread {
handleTransactions(transactions)
@@ -98,7 +100,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
// MARK: - Products and payments
- func requestProducts(with productIdentifiers: Set<AppStoreSubscription>, completionHandler: @escaping (OperationCompletion<SKProductsResponse, Swift.Error>) -> Void) -> Cancellable {
+ func requestProducts(
+ with productIdentifiers: Set<AppStoreSubscription>,
+ completionHandler: @escaping (OperationCompletion<SKProductsResponse, Swift.Error>) -> Void
+ ) -> Cancellable {
let productIdentifiers = productIdentifiers.productIdentifiersSet
let operation = ProductsRequestOperation(
productIdentifiers: productIdentifiers,
@@ -113,9 +118,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
func addPayment(_ payment: SKPayment, for accountToken: String) {
var task: Cancellable?
- let backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(withName: "Validate account token") {
- task?.cancel()
- }
+ let backgroundTaskIdentifier = UIApplication.shared
+ .beginBackgroundTask(withName: "Validate account token") {
+ task?.cancel()
+ }
// Validate account token before adding new payment to the queue.
task = accountsProxy.getAccountData(
@@ -129,7 +135,7 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
self.associateAccountToken(accountToken, and: payment)
self.paymentQueue.add(payment)
- case .failure(let error):
+ case let .failure(error):
self.observerList.forEach { observer in
observer.appStorePaymentManager(
self,
@@ -156,11 +162,20 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
}
}
- func restorePurchases(for accountToken: String, completionHandler: @escaping (OperationCompletion<REST.CreateApplePaymentResponse, AppStorePaymentManager.Error>) -> Void) -> Cancellable {
- return sendAppStoreReceipt(accountToken: accountToken, forceRefresh: true, completionHandler: completionHandler)
+ func restorePurchases(
+ for accountToken: String,
+ completionHandler: @escaping (OperationCompletion<
+ REST.CreateApplePaymentResponse,
+ AppStorePaymentManager.Error
+ >) -> Void
+ ) -> Cancellable {
+ return sendAppStoreReceipt(
+ accountToken: accountToken,
+ forceRefresh: true,
+ completionHandler: completionHandler
+ )
}
-
// MARK: - Private methods
private func associateAccountToken(_ token: String, and payment: SKPayment) {
@@ -180,7 +195,12 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
}
}
- private func sendAppStoreReceipt(accountToken: String, forceRefresh: Bool, completionHandler: @escaping (OperationCompletion<REST.CreateApplePaymentResponse, Error>) -> Void) -> Cancellable {
+ private func sendAppStoreReceipt(
+ accountToken: String,
+ forceRefresh: Bool,
+ completionHandler: @escaping (OperationCompletion<REST.CreateApplePaymentResponse, Error>)
+ -> Void
+ ) -> Cancellable {
let operation = SendAppStoreReceiptOperation(
apiProxy: apiProxy,
accountToken: accountToken,
@@ -214,7 +234,10 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
logger.info("Deferred \(transaction.payment.productIdentifier)")
case .failed:
- logger.error("Failed to purchase \(transaction.payment.productIdentifier): \(transaction.error?.localizedDescription ?? "No error")")
+ logger
+ .error(
+ "Failed to purchase \(transaction.payment.productIdentifier): \(transaction.error?.localizedDescription ?? "No error")"
+ )
didFailPurchase(transaction: transaction)
@@ -246,7 +269,8 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
transaction: transaction,
payment: transaction.payment,
accountToken: accountToken,
- didFailWithError: .storePayment(transaction.error!))
+ didFailWithError: .storePayment(transaction.error!)
+ )
}
} else {
observerList.forEach { observer in
@@ -255,7 +279,8 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
transaction: transaction,
payment: transaction.payment,
accountToken: nil,
- didFailWithError: .noAccountSet)
+ didFailWithError: .noAccountSet
+ )
}
}
}
@@ -268,14 +293,15 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
transaction: transaction,
payment: transaction.payment,
accountToken: nil,
- didFailWithError: .noAccountSet)
+ didFailWithError: .noAccountSet
+ )
}
return
}
_ = sendAppStoreReceipt(accountToken: accountToken, forceRefresh: false) { completion in
switch completion {
- case .success(let response):
+ case let .success(response):
self.paymentQueue.finishTransaction(transaction)
self.observerList.forEach { observer in
@@ -283,17 +309,19 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
self,
transaction: transaction,
accountToken: accountToken,
- didFinishWithResponse: response)
+ didFinishWithResponse: response
+ )
}
- case .failure(let error):
+ case let .failure(error):
self.observerList.forEach { observer in
observer.appStorePaymentManager(
self,
transaction: transaction,
payment: transaction.payment,
accountToken: accountToken,
- didFailWithError: error)
+ didFailWithError: error
+ )
}
case .cancelled:
@@ -301,5 +329,4 @@ class AppStorePaymentManager: NSObject, SKPaymentTransactionObserver {
}
}
}
-
}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift
index a56fa2d1e2..8dc848c854 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentManagerDelegate.swift
@@ -10,9 +10,10 @@ import Foundation
import StoreKit
protocol AppStorePaymentManagerDelegate: AnyObject {
-
/// Return the account token associated with the payment.
/// Usually called for unfinished transactions coming back after the app was restarted.
- func appStorePaymentManager(_ manager: AppStorePaymentManager,
- didRequestAccountTokenFor payment: SKPayment) -> String?
+ func appStorePaymentManager(
+ _ manager: AppStorePaymentManager,
+ didRequestAccountTokenFor payment: SKPayment
+ ) -> String?
}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift
index ad37c707c4..4a82b8fa87 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/AppStorePaymentObserver.swift
@@ -10,17 +10,18 @@ import Foundation
import StoreKit
protocol AppStorePaymentObserver: AnyObject {
-
func appStorePaymentManager(
_ manager: AppStorePaymentManager,
transaction: SKPaymentTransaction?,
payment: SKPayment,
accountToken: String?,
- didFailWithError error: AppStorePaymentManager.Error)
+ didFailWithError error: AppStorePaymentManager.Error
+ )
func appStorePaymentManager(
_ manager: AppStorePaymentManager,
transaction: SKPaymentTransaction,
accountToken: String,
- didFinishWithResponse response: REST.CreateApplePaymentResponse)
+ didFinishWithResponse response: REST.CreateApplePaymentResponse
+ )
}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift b/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift
index 4c126bfdc3..37fa3342cb 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/AppStoreSubscription.swift
@@ -34,6 +34,6 @@ extension SKProduct {
extension Set where Element == AppStoreSubscription {
var productIdentifiersSet: Set<String> {
- Set<String>(self.map { $0.rawValue })
+ Set<String>(map { $0.rawValue })
}
}
diff --git a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift b/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
index a95707b5c6..04a7813d4a 100644
--- a/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
+++ b/ios/MullvadVPN/AppStorePaymentManager/SendAppStoreReceiptOperation.swift
@@ -9,7 +9,10 @@
import Foundation
import Logging
-class SendAppStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentResponse, AppStorePaymentManager.Error> {
+class SendAppStoreReceiptOperation: ResultOperation<
+ REST.CreateApplePaymentResponse,
+ AppStorePaymentManager.Error
+> {
private let apiProxy: REST.APIProxy
private let accountToken: String
private let forceRefresh: Bool
@@ -19,7 +22,13 @@ class SendAppStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentRespo
private let logger = Logger(label: "SendAppStoreReceiptOperation")
- init(apiProxy: REST.APIProxy, accountToken: String, forceRefresh: Bool, receiptProperties: [String: Any]?, completionHandler: @escaping CompletionHandler) {
+ init(
+ apiProxy: REST.APIProxy,
+ accountToken: String,
+ forceRefresh: Bool,
+ receiptProperties: [String: Any]?,
+ completionHandler: @escaping CompletionHandler
+ ) {
self.apiProxy = apiProxy
self.accountToken = accountToken
self.forceRefresh = forceRefresh
@@ -41,13 +50,19 @@ class SendAppStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentRespo
}
override func main() {
- fetchReceiptTask = AppStoreReceipt.fetch(forceRefresh: self.forceRefresh, receiptProperties: self.receiptProperties) { completion in
+ fetchReceiptTask = AppStoreReceipt.fetch(
+ forceRefresh: forceRefresh,
+ receiptProperties: receiptProperties
+ ) { completion in
switch completion {
- case .success(let receiptData):
+ case let .success(receiptData):
self.sendReceipt(receiptData)
- case .failure(let error):
- self.logger.error(chainedError: error, message: "Failed to fetch the AppStore receipt.")
+ case let .failure(error):
+ self.logger.error(
+ chainedError: error,
+ message: "Failed to fetch the AppStore receipt."
+ )
self.finish(completion: .failure(.readReceipt(error)))
case .cancelled:
@@ -58,22 +73,29 @@ class SendAppStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentRespo
private func sendReceipt(_ receiptData: Data) {
submitReceiptTask = apiProxy.createApplePayment(
- accountNumber: self.accountToken,
+ accountNumber: accountToken,
receiptString: receiptData,
- retryStrategy: .noRetry) { result in
- switch result {
- case .success(let response):
- self.logger.info("AppStore receipt was processed. Time added: \(response.timeAdded), New expiry: \(response.newExpiry.logFormatDate())")
- self.finish(completion: .success(response))
+ retryStrategy: .noRetry
+ ) { result in
+ switch result {
+ case let .success(response):
+ self.logger
+ .info(
+ "AppStore receipt was processed. Time added: \(response.timeAdded), New expiry: \(response.newExpiry.logFormatDate())"
+ )
+ self.finish(completion: .success(response))
- case .failure(let error):
- self.logger.error(chainedError: error, message: "Failed to send the AppStore receipt.")
- self.finish(completion: .failure(.sendReceipt(error)))
+ case let .failure(error):
+ self.logger.error(
+ chainedError: error,
+ message: "Failed to send the AppStore receipt."
+ )
+ self.finish(completion: .failure(.sendReceipt(error)))
- case .cancelled:
- self.logger.debug("Receipt submission cancelled.")
- self.finish(completion: .cancelled)
- }
+ case .cancelled:
+ self.logger.debug("Receipt submission cancelled.")
+ self.finish(completion: .cancelled)
}
+ }
}
}
diff --git a/ios/MullvadVPN/AppStoreReceipt.swift b/ios/MullvadVPN/AppStoreReceipt.swift
index a565bd4012..c4bb18060c 100644
--- a/ios/MullvadVPN/AppStoreReceipt.swift
+++ b/ios/MullvadVPN/AppStoreReceipt.swift
@@ -42,7 +42,11 @@ enum AppStoreReceipt {
/// Read AppStore receipt from disk or refresh it from AppStore if it's missing.
/// This call may trigger a sign in with AppStore prompt to appear.
- static func fetch(forceRefresh: Bool = false, receiptProperties: [String: Any]? = nil, completionHandler: @escaping (OperationCompletion<Data, Error>) -> Void) -> Cancellable {
+ static func fetch(
+ forceRefresh: Bool = false,
+ receiptProperties: [String: Any]? = nil,
+ completionHandler: @escaping (OperationCompletion<Data, Error>) -> Void
+ ) -> Cancellable {
let operation = FetchAppStoreReceiptOperation(
forceRefresh: forceRefresh,
receiptProperties: receiptProperties,
@@ -59,7 +63,9 @@ enum AppStoreReceipt {
}
}
-fileprivate class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreReceipt.Error>, SKRequestDelegate {
+private class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreReceipt.Error>,
+ SKRequestDelegate
+{
private var request: SKReceiptRefreshRequest?
private let receiptProperties: [String: Any]?
private let forceRefresh: Bool
@@ -68,8 +74,7 @@ fileprivate class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreR
forceRefresh: Bool,
receiptProperties: [String: Any]?,
completionHandler: @escaping (Completion) -> Void
- )
- {
+ ) {
self.forceRefresh = forceRefresh
self.receiptProperties = receiptProperties
@@ -99,7 +104,7 @@ fileprivate class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreR
}
override func operationDidCancel() {
- self.request?.cancel()
+ request?.cancel()
}
// - MARK: SKRequestDelegate
@@ -150,13 +155,14 @@ fileprivate class FetchAppStoreReceiptOperation: ResultOperation<Data, AppStoreR
let readResult = Result { try Data(contentsOf: appStoreReceiptURL) }
- return readResult.mapError { (error) -> AppStoreReceipt.Error in
- if let cocoaError = error as? CocoaError, cocoaError.code == .fileReadNoSuchFile || cocoaError.code == .fileNoSuchFile {
+ return readResult.mapError { error -> AppStoreReceipt.Error in
+ if let cocoaError = error as? CocoaError,
+ cocoaError.code == .fileReadNoSuchFile || cocoaError.code == .fileNoSuchFile
+ {
return .doesNotExist
} else {
return .io(error)
}
}
}
-
}
diff --git a/ios/MullvadVPN/ApplicationConfiguration.swift b/ios/MullvadVPN/ApplicationConfiguration.swift
index f00413a296..615abf0880 100644
--- a/ios/MullvadVPN/ApplicationConfiguration.swift
+++ b/ios/MullvadVPN/ApplicationConfiguration.swift
@@ -26,17 +26,24 @@ class ApplicationConfiguration {
/// Container URL for security group
static var containerURL: URL? {
- return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Self.securityGroupIdentifier)
+ return FileManager.default
+ .containerURL(forSecurityApplicationGroupIdentifier: Self.securityGroupIdentifier)
}
/// The main application log file located in a shared container
static var mainApplicationLogFileURL: URL? {
- return Self.containerURL?.appendingPathComponent("Logs/net.mullvad.MullvadVPN.log", isDirectory: false)
+ return Self.containerURL?.appendingPathComponent(
+ "Logs/net.mullvad.MullvadVPN.log",
+ isDirectory: false
+ )
}
/// The packet tunnel log file located in a shared container
static var packetTunnelLogFileURL: URL? {
- return Self.containerURL?.appendingPathComponent("Logs/net.mullvad.MullvadVPN.PacketTunnel.log", isDirectory: false)
+ return Self.containerURL?.appendingPathComponent(
+ "Logs/net.mullvad.MullvadVPN.PacketTunnel.log",
+ isDirectory: false
+ )
}
/// All log files located in a shared container
diff --git a/ios/MullvadVPN/AutomaticKeyboardResponder.swift b/ios/MullvadVPN/AutomaticKeyboardResponder.swift
index eef063261d..ee3a97bfa8 100644
--- a/ios/MullvadVPN/AutomaticKeyboardResponder.swift
+++ b/ios/MullvadVPN/AutomaticKeyboardResponder.swift
@@ -6,8 +6,8 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
class AutomaticKeyboardResponder {
weak var targetView: UIView?
@@ -21,13 +21,28 @@ class AutomaticKeyboardResponder {
init<T: UIView>(targetView: T, handler: @escaping (T, CGFloat) -> Void) {
self.targetView = targetView
- self.handler = { (view, adjustment) in
+ self.handler = { view, adjustment in
handler(view as! T, adjustment)
}
- NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIWindow.keyboardWillChangeFrameNotification, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIWindow.keyboardWillShowNotification, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide(_:)), name: UIWindow.keyboardDidHideNotification, object: nil)
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(keyboardWillChangeFrame(_:)),
+ name: UIWindow.keyboardWillChangeFrameNotification,
+ object: nil
+ )
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(keyboardWillShow(_:)),
+ name: UIWindow.keyboardWillShowNotification,
+ object: nil
+ )
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(keyboardDidHide(_:)),
+ name: UIWindow.keyboardDidHideNotification,
+ object: nil
+ )
}
func updateContentInsets() {
@@ -59,11 +74,12 @@ class AutomaticKeyboardResponder {
// MARK: - Private
private func handleKeyboardNotification(_ notification: Notification) {
- guard let keyboardFrameValue = notification.userInfo?[UIWindow.keyboardFrameEndUserInfoKey] as? NSValue else { return }
+ guard let keyboardFrameValue = notification
+ .userInfo?[UIWindow.keyboardFrameEndUserInfoKey] as? NSValue else { return }
lastKeyboardRect = keyboardFrameValue.cgRectValue
- self.adjustContentInsets(keyboardRect: keyboardFrameValue.cgRectValue)
+ adjustContentInsets(keyboardRect: keyboardFrameValue.cgRectValue)
}
private func addPresentationControllerObserver() {
@@ -77,11 +93,16 @@ class AutomaticKeyboardResponder {
return
}
- presentationFrameObserver = containerView.observe(\.frame, options: [.new], changeHandler: { [weak self] (containingView, change) in
- guard let self = self, let keyboardFrameValue = self.lastKeyboardRect else { return }
+ presentationFrameObserver = containerView.observe(
+ \.frame,
+ options: [.new],
+ changeHandler: { [weak self] containingView, change in
+ guard let self = self,
+ let keyboardFrameValue = self.lastKeyboardRect else { return }
- self.adjustContentInsets(keyboardRect: keyboardFrameValue)
- })
+ self.adjustContentInsets(keyboardRect: keyboardFrameValue)
+ }
+ )
}
/// Returns the first parent controller in the responder chain
@@ -105,7 +126,7 @@ class AutomaticKeyboardResponder {
// Find the container view that private `_UIFormSheetPresentationController` moves
// along with the keyboard.
- return iterator.first { (view) -> Bool in
+ return iterator.first { view -> Bool in
return view.description.starts(with: "<UIDropShadowView")
}
}
@@ -145,10 +166,9 @@ class AutomaticKeyboardResponder {
}
extension AutomaticKeyboardResponder {
-
/// A convenience initializer that automatically assigns the offset to the scroll view subclasses
convenience init<T: UIScrollView>(targetView: T) {
- self.init(targetView: targetView) { (scrollView, offset) in
+ self.init(targetView: targetView) { scrollView, offset in
if scrollView.canBecomeFirstResponder {
scrollView.contentInset.bottom = targetView.isFirstResponder ? offset : 0
scrollView.scrollIndicatorInsets.bottom = targetView.isFirstResponder ? offset : 0
diff --git a/ios/MullvadVPN/Bundle+ProductVersion.swift b/ios/MullvadVPN/Bundle+ProductVersion.swift
index a2ed526588..1030096834 100644
--- a/ios/MullvadVPN/Bundle+ProductVersion.swift
+++ b/ios/MullvadVPN/Bundle+ProductVersion.swift
@@ -9,7 +9,6 @@
import Foundation
extension Bundle {
-
/// Returns the product version string based on the following rules:
///
/// 1. Dev builds (debug): XXXX.YY-devZ
@@ -19,17 +18,17 @@ extension Bundle {
/// Note: XXXX.YY is an app version (i.e 2020.5) and Z is a build number (i.e 1)
var productVersion: String {
let version = object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "???"
- let buildNumber = object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? "???"
+ let buildNumber = object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ??
+ "???"
#if DEBUG
- return "\(version)-dev\(buildNumber)"
+ return "\(version)-dev\(buildNumber)"
#else
- if appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" {
- return "\(version)-beta\(buildNumber)"
- } else {
- return version
- }
+ if appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" {
+ return "\(version)-beta\(buildNumber)"
+ } else {
+ return version
+ }
#endif
}
-
}
diff --git a/ios/MullvadVPN/CharacterSet+IPAddress.swift b/ios/MullvadVPN/CharacterSet+IPAddress.swift
index f15d134f84..2131398cc9 100644
--- a/ios/MullvadVPN/CharacterSet+IPAddress.swift
+++ b/ios/MullvadVPN/CharacterSet+IPAddress.swift
@@ -16,5 +16,4 @@ extension CharacterSet {
static var ipv6AddressCharset: CharacterSet {
return CharacterSet(charactersIn: "0123456789abcdef:.")
}
-
}
diff --git a/ios/MullvadVPN/CodingErrors+ChainedError.swift b/ios/MullvadVPN/CodingErrors+ChainedError.swift
index e14d61473b..1dfa73f923 100644
--- a/ios/MullvadVPN/CodingErrors+ChainedError.swift
+++ b/ios/MullvadVPN/CodingErrors+ChainedError.swift
@@ -11,13 +11,13 @@ import Foundation
extension DecodingError: CustomChainedErrorDescriptionProtocol {
var customErrorDescription: String? {
switch self {
- case .typeMismatch(let type, let context):
+ case let .typeMismatch(type, context):
return "Type mismatch, expected \(type) for key at \"\(context.codingPath.codingPathString)\"."
- case .valueNotFound(_, let context):
+ case let .valueNotFound(_, context):
return "Value not found at \"\(context.codingPath.codingPathString)\"."
- case .keyNotFound(let codingKey, let context):
+ case let .keyNotFound(codingKey, context):
return "Key \"\(codingKey.stringValue)\" not found at \"\(context.codingPath.codingPathString)\"."
case .dataCorrupted:
@@ -32,7 +32,7 @@ extension DecodingError: CustomChainedErrorDescriptionProtocol {
extension EncodingError: CustomChainedErrorDescriptionProtocol {
var customErrorDescription: String? {
switch self {
- case .invalidValue(_, let context):
+ case let .invalidValue(_, context):
return "Invalid value at \"\(context.codingPath.codingPathString)\""
@unknown default:
diff --git a/ios/MullvadVPN/ConnectContentView.swift b/ios/MullvadVPN/ConnectContentView.swift
index 01b22f18d9..f158aa90eb 100644
--- a/ios/MullvadVPN/ConnectContentView.swift
+++ b/ios/MullvadVPN/ConnectContentView.swift
@@ -6,8 +6,8 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import MapKit
+import UIKit
class ConnectContentView: UIView {
enum ActionButton {
@@ -84,13 +84,9 @@ class ConnectContentView: UIView {
return button
}()
- lazy var selectLocationBlurView: TranslucentButtonBlurView = {
- return TranslucentButtonBlurView(button: selectLocationButton)
- }()
+ lazy var selectLocationBlurView = TranslucentButtonBlurView(button: selectLocationButton)
- lazy var cancelButtonBlurView: TranslucentButtonBlurView = {
- return TranslucentButtonBlurView(button: cancelButton)
- }()
+ lazy var cancelButtonBlurView = TranslucentButtonBlurView(button: cancelButton)
let splitDisconnectButton: DisconnectSplitButton = {
let button = DisconnectSplitButton()
@@ -139,7 +135,7 @@ class ConnectContentView: UIView {
}
private func addSubviews() {
- mapView.frame = self.bounds
+ mapView.frame = bounds
locationContainerView.addSubview(secureLabel)
locationContainerView.addSubview(cityLabel)
@@ -158,12 +154,16 @@ class ConnectContentView: UIView {
containerView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
containerView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
- locationContainerView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor),
+ locationContainerView.topAnchor
+ .constraint(greaterThanOrEqualTo: containerView.topAnchor),
locationContainerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
locationContainerView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
activityIndicator.centerXAnchor.constraint(equalTo: mapView.centerXAnchor),
- locationContainerView.topAnchor.constraint(equalTo: activityIndicator.bottomAnchor, constant: 22),
+ locationContainerView.topAnchor.constraint(
+ equalTo: activityIndicator.bottomAnchor,
+ constant: 22
+ ),
secureLabel.topAnchor.constraint(equalTo: locationContainerView.topAnchor),
secureLabel.leadingAnchor.constraint(equalTo: locationContainerView.leadingAnchor),
@@ -178,14 +178,20 @@ class ConnectContentView: UIView {
countryLabel.trailingAnchor.constraint(equalTo: locationContainerView.trailingAnchor),
countryLabel.bottomAnchor.constraint(equalTo: locationContainerView.bottomAnchor),
- connectionPanel.topAnchor.constraint(equalTo: locationContainerView.bottomAnchor, constant: 8),
+ connectionPanel.topAnchor.constraint(
+ equalTo: locationContainerView.bottomAnchor,
+ constant: 8
+ ),
connectionPanel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
connectionPanel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
- buttonsStackView.topAnchor.constraint(equalTo: connectionPanel.bottomAnchor, constant: 24),
+ buttonsStackView.topAnchor.constraint(
+ equalTo: connectionPanel.bottomAnchor,
+ constant: 24
+ ),
buttonsStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
- buttonsStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
+ buttonsStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
])
updateTraitConstraints()
@@ -197,16 +203,24 @@ class ConnectContentView: UIView {
switch traitCollection.userInterfaceIdiom {
case .pad:
// Max container width is 70% width of iPad in portrait mode
- let maxWidth = min(UIScreen.main.nativeBounds.width * 0.7, UIMetrics.maximumSplitViewContentContainerWidth)
+ let maxWidth = min(
+ UIScreen.main.nativeBounds.width * 0.7,
+ UIMetrics.maximumSplitViewContentContainerWidth
+ )
layoutConstraints.append(contentsOf: [
- containerView.trailingAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor),
+ containerView.trailingAnchor
+ .constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor),
containerView.widthAnchor.constraint(equalToConstant: maxWidth)
- .withPriority(.defaultHigh)
+ .withPriority(.defaultHigh),
])
case .phone:
- layoutConstraints.append(containerView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor))
+ layoutConstraints
+ .append(
+ containerView.trailingAnchor
+ .constraint(equalTo: layoutMarginsGuide.trailingAnchor)
+ )
default:
break
@@ -226,14 +240,14 @@ class ConnectContentView: UIView {
}
private func setArrangedButtons(_ newButtons: [UIView]) {
- buttonsStackView.arrangedSubviews.forEach { (button) in
+ buttonsStackView.arrangedSubviews.forEach { button in
if !newButtons.contains(button) {
buttonsStackView.removeArrangedSubview(button)
button.removeFromSuperview()
}
}
- newButtons.forEach { (button) in
+ newButtons.forEach { button in
buttonsStackView.addArrangedSubview(button)
}
}
diff --git a/ios/MullvadVPN/ConnectViewController.swift b/ios/MullvadVPN/ConnectViewController.swift
index 6a3fe21d0c..02e4a5ee6e 100644
--- a/ios/MullvadVPN/ConnectViewController.swift
+++ b/ios/MullvadVPN/ConnectViewController.swift
@@ -6,13 +6,13 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import UIKit
-import MapKit
import Logging
+import MapKit
+import UIKit
class CustomOverlayRenderer: MKOverlayRenderer {
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
- let drawRect = self.rect(for: mapRect)
+ let drawRect = rect(for: mapRect)
context.setFillColor(UIColor.secondaryColor.cgColor)
context.fill(drawRect)
}
@@ -23,7 +23,6 @@ protocol ConnectViewControllerDelegate: AnyObject {
}
class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainment, TunnelObserver {
-
private static let geoJSONSourceFileName = "countries.geo.json"
private static let locationMarkerReuseIdentifier = "location"
@@ -82,15 +81,35 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
override func viewDidLoad() {
super.viewDidLoad()
- contentView.connectButton.addTarget(self, action: #selector(handleConnect(_:)), for: .touchUpInside)
- contentView.cancelButton.addTarget(self, action: #selector(handleDisconnect(_:)), for: .touchUpInside)
- contentView.splitDisconnectButton.primaryButton.addTarget(self, action: #selector(handleDisconnect(_:)), for: .touchUpInside)
- contentView.splitDisconnectButton.secondaryButton.addTarget(self, action: #selector(handleReconnect(_:)), for: .touchUpInside)
+ contentView.connectButton.addTarget(
+ self,
+ action: #selector(handleConnect(_:)),
+ for: .touchUpInside
+ )
+ contentView.cancelButton.addTarget(
+ self,
+ action: #selector(handleDisconnect(_:)),
+ for: .touchUpInside
+ )
+ contentView.splitDisconnectButton.primaryButton.addTarget(
+ self,
+ action: #selector(handleDisconnect(_:)),
+ for: .touchUpInside
+ )
+ contentView.splitDisconnectButton.secondaryButton.addTarget(
+ self,
+ action: #selector(handleReconnect(_:)),
+ for: .touchUpInside
+ )
- contentView.selectLocationButton.addTarget(self, action: #selector(handleSelectLocation(_:)), for: .touchUpInside)
+ contentView.selectLocationButton.addTarget(
+ self,
+ action: #selector(handleSelectLocation(_:)),
+ for: .touchUpInside
+ )
TunnelManager.shared.addObserver(self)
- self.tunnelState = TunnelManager.shared.tunnelStatus.state
+ tunnelState = TunnelManager.shared.tunnelStatus.state
addSubviews()
setupMapView()
@@ -104,7 +123,8 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
super.traitCollectionDidChange(previousTraitCollection)
if previousTraitCollection?.userInterfaceIdiom != traitCollection.userInterfaceIdiom ||
- previousTraitCollection?.horizontalSizeClass != traitCollection.horizontalSizeClass {
+ previousTraitCollection?.horizontalSizeClass != traitCollection.horizontalSizeClass
+ {
updateTraitDependentViews()
}
}
@@ -128,14 +148,17 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
contentView.topAnchor.constraint(equalTo: view.topAnchor),
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
// Force layout since we rely on view frames when positioning map camera.
view.layoutIfNeeded()
}
- override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+ override func viewWillTransition(
+ to size: CGSize,
+ with coordinator: UIViewControllerTransitionCoordinator
+ ) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in }, completion: { context in
@@ -149,7 +172,10 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
@@ -179,14 +205,18 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
comment: ""
), for: .normal
)
- contentView.selectLocationButton.setTitle(tunnelState.localizedTitleForSelectLocationButton, for: .normal)
+ contentView.selectLocationButton.setTitle(
+ tunnelState.localizedTitleForSelectLocationButton,
+ for: .normal
+ )
contentView.cancelButton.setTitle(
NSLocalizedString(
"CANCEL_BUTTON_TITLE",
tableName: "Main",
value: "Cancel",
comment: ""
- ), for: .normal)
+ ), for: .normal
+ )
contentView.splitDisconnectButton.primaryButton.setTitle(
NSLocalizedString(
"DISCONNECT_BUTTON_TITLE",
@@ -206,7 +236,7 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
}
private func updateTraitDependentViews() {
- contentView.setActionButtons(tunnelState.actionButtons(traitCollection: self.traitCollection))
+ contentView.setActionButtons(tunnelState.actionButtons(traitCollection: traitCollection))
}
private func attributedStringForLocation(string: String) -> NSAttributedString {
@@ -214,28 +244,32 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
paragraphStyle.lineSpacing = 0
paragraphStyle.lineHeightMultiple = 0.80
return NSAttributedString(string: string, attributes: [
- .paragraphStyle: paragraphStyle])
+ .paragraphStyle: paragraphStyle,
+ ])
}
private func updateTunnelRelay() {
switch tunnelState {
- case .connecting(let tunnelRelay):
+ case let .connecting(tunnelRelay):
setTunnelRelay(tunnelRelay)
- case .connected(let tunnelRelay), .reconnecting(let tunnelRelay):
+ case let .connected(tunnelRelay), let .reconnecting(tunnelRelay):
setTunnelRelay(tunnelRelay)
case .disconnected, .disconnecting, .pendingReconnect:
setTunnelRelay(nil)
}
- contentView.locationContainerView.accessibilityLabel = tunnelState.localizedAccessibilityLabel
+ contentView.locationContainerView.accessibilityLabel = tunnelState
+ .localizedAccessibilityLabel
}
private func setTunnelRelay(_ tunnelRelay: PacketTunnelRelay?) {
if let tunnelRelay = tunnelRelay {
- contentView.cityLabel.attributedText = attributedStringForLocation(string: tunnelRelay.location.city)
- contentView.countryLabel.attributedText = attributedStringForLocation(string: tunnelRelay.location.country)
+ contentView.cityLabel
+ .attributedText = attributedStringForLocation(string: tunnelRelay.location.city)
+ contentView.countryLabel
+ .attributedText = attributedStringForLocation(string: tunnelRelay.location.country)
contentView.connectionPanel.dataSource = ConnectionPanelData(
inAddress: "\(tunnelRelay.ipv4Relay) UDP",
@@ -253,7 +287,10 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
private func locationMarkerOffset() -> CGPoint {
// Compute the activity indicator frame within the view coordinate system.
- let activityIndicatorFrame = contentView.activityIndicator.convert(contentView.activityIndicator.bounds, to: view)
+ let activityIndicatorFrame = contentView.activityIndicator.convert(
+ contentView.activityIndicator.bounds,
+ to: view
+ )
// Compute the offset to align the marker on the map with activity indicator.
let offsetY = activityIndicatorFrame.midY - contentView.mapView.frame.midY
@@ -261,9 +298,13 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
return CGPoint(x: 0, y: offsetY)
}
- private func computeCoordinateRegion(center: CLLocationCoordinate2D, offset: CGPoint) -> MKCoordinateRegion {
+ private func computeCoordinateRegion(
+ center: CLLocationCoordinate2D,
+ offset: CGPoint
+ ) -> MKCoordinateRegion {
let span = MKCoordinateSpan(latitudeDelta: 30, longitudeDelta: 30)
- var region = contentView.mapView.regionThatFits(MKCoordinateRegion(center: center, span: span))
+ var region = contentView.mapView
+ .regionThatFits(MKCoordinateRegion(center: center, span: span))
let latitudeDeltaPerPoint = region.span.latitudeDelta / contentView.mapView.frame.height
region.center = center
@@ -274,7 +315,7 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
private func updateLocation(animated: Bool) {
switch tunnelState {
- case .connecting(let tunnelRelay):
+ case let .connecting(tunnelRelay):
removeLocationMarker()
contentView.activityIndicator.startAnimating()
@@ -284,13 +325,13 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
unsetLocation(animated: animated)
}
- case .reconnecting(let tunnelRelay):
+ case let .reconnecting(tunnelRelay):
removeLocationMarker()
contentView.activityIndicator.startAnimating()
setLocation(coordinate: tunnelRelay.location.geoCoordinate, animated: animated)
- case .connected(let tunnelRelay):
+ case let .connected(tunnelRelay):
// Show marker right away if activity indicator is not animating, i.e when the app
// launches with connected tunnel.
let showMarkerRightAway = !contentView.activityIndicator.isAnimating
@@ -299,7 +340,10 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
addLocationMarker(coordinate: tunnelRelay.location.geoCoordinate)
}
- setLocation(coordinate: tunnelRelay.location.geoCoordinate, animated: animated) { [weak self] in
+ setLocation(
+ coordinate: tunnelRelay.location.geoCoordinate,
+ animated: animated
+ ) { [weak self] in
if !showMarkerRightAway {
self?.contentView.activityIndicator.stopAnimating()
self?.addLocationMarker(coordinate: tunnelRelay.location.geoCoordinate)
@@ -327,7 +371,11 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
contentView.mapView.removeAnnotation(locationMarker)
}
- private func setLocation(coordinate: CLLocationCoordinate2D, animated: Bool, animationDidEnd: (() -> Void)? = nil) {
+ private func setLocation(
+ coordinate: CLLocationCoordinate2D,
+ animated: Bool,
+ animationDidEnd: (() -> Void)? = nil
+ ) {
let markerOffset = locationMarkerOffset()
let region = computeCoordinateRegion(center: coordinate, offset: markerOffset)
@@ -378,7 +426,7 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
notificationView.topAnchor.constraint(equalTo: view.topAnchor),
notificationView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
notificationView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- notificationView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ notificationView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
@@ -491,7 +539,6 @@ class ConnectViewController: UIViewController, MKMapViewDelegate, RootContainmen
}
private extension TunnelState {
-
var textColorForSecureLabel: UIColor {
switch self {
case .connecting, .reconnecting:
@@ -585,7 +632,7 @@ private extension TunnelState {
comment: ""
)
- case .connected(let tunnelInfo):
+ case let .connected(tunnelInfo):
return String(
format: NSLocalizedString(
"TUNNEL_STATE_CONNECTED_ACCESSIBILITY_LABEL",
@@ -605,7 +652,7 @@ private extension TunnelState {
comment: ""
)
- case .reconnecting(let tunnelInfo):
+ case let .reconnecting(tunnelInfo):
return String(
format: NSLocalizedString(
"TUNNEL_STATE_RECONNECTING_ACCESSIBILITY_LABEL",
@@ -665,7 +712,6 @@ private extension TunnelState {
return []
}
}
-
}
private extension MKCoordinateRegion {
@@ -675,5 +721,4 @@ private extension MKCoordinateRegion {
fabs(span.latitudeDelta - other.span.latitudeDelta) <= .ulpOfOne &&
fabs(span.longitudeDelta - other.span.longitudeDelta) <= .ulpOfOne
}
-
}
diff --git a/ios/MullvadVPN/ConnectionPanelView.swift b/ios/MullvadVPN/ConnectionPanelView.swift
index c4ea1c7b6a..1a491d1667 100644
--- a/ios/MullvadVPN/ConnectionPanelView.swift
+++ b/ios/MullvadVPN/ConnectionPanelView.swift
@@ -15,7 +15,6 @@ struct ConnectionPanelData {
}
class ConnectionPanelView: UIView {
-
var dataSource: ConnectionPanelData? {
didSet {
didChangeDataSource()
@@ -28,7 +27,7 @@ class ConnectionPanelView: UIView {
}
}
- var connectedRelayName: String = "" {
+ var connectedRelayName = "" {
didSet {
collapseButton.setTitle(connectedRelayName, for: .normal)
collapseButton.accessibilityLabel = NSLocalizedString(
@@ -38,8 +37,11 @@ class ConnectionPanelView: UIView {
comment: ""
)
collapseButton.accessibilityAttributedValue = NSAttributedString(
- string: connectedRelayName.replacingOccurrences(of: "-wireguard", with: " WireGuard"),
- attributes: [ .accessibilitySpeechLanguage: "en" ]
+ string: connectedRelayName.replacingOccurrences(
+ of: "-wireguard",
+ with: " WireGuard"
+ ),
+ attributes: [.accessibilitySpeechLanguage: "en"]
)
}
}
@@ -107,7 +109,7 @@ class ConnectionPanelView: UIView {
textLabelLayoutGuide.trailingAnchor
.constraint(equalTo: inAddressRow.textLabelLayoutGuide.trailingAnchor),
textLabelLayoutGuide.trailingAnchor
- .constraint(equalTo: outAddressRow.textLabelLayoutGuide.trailingAnchor)
+ .constraint(equalTo: outAddressRow.textLabelLayoutGuide.trailingAnchor),
])
updateConnectionInfoVisibility()
@@ -138,7 +140,10 @@ class ConnectionPanelView: UIView {
collapseButton.style = showsConnectionInfo ? .up : .down
if collapseButton.accessibilityElementIsFocused(), showsConnectionInfo {
- UIAccessibility.post(notification: .layoutChanged, argument: stackView.arrangedSubviews.first)
+ UIAccessibility.post(
+ notification: .layoutChanged,
+ argument: stackView.arrangedSubviews.first
+ )
}
updateCollapseButtonAccessibilityHint()
}
@@ -163,7 +168,6 @@ class ConnectionPanelView: UIView {
}
class ConnectionPanelAddressRow: UIView {
-
private let textLabel: UILabel = {
let textLabel = UILabel()
textLabel.font = .systemFont(ofSize: 17)
@@ -227,7 +231,7 @@ class ConnectionPanelAddressRow: UIView {
textLabelLayoutGuide.leadingAnchor.constraint(equalTo: textLabel.leadingAnchor),
textLabelLayoutGuide.trailingAnchor.constraint(equalTo: textLabel.trailingAnchor),
textLabelLayoutGuide.topAnchor.constraint(equalTo: textLabel.topAnchor),
- textLabelLayoutGuide.bottomAnchor.constraint(equalTo: textLabel.bottomAnchor)
+ textLabelLayoutGuide.bottomAnchor.constraint(equalTo: textLabel.bottomAnchor),
])
}
@@ -237,7 +241,6 @@ class ConnectionPanelAddressRow: UIView {
}
class ConnectionPanelCollapseButton: CustomButton {
-
enum Style {
case up, down
@@ -282,5 +285,4 @@ class ConnectionPanelCollapseButton: CustomButton {
private func updateButtonImage() {
setImage(style.image, for: .normal)
}
-
}
diff --git a/ios/MullvadVPN/ConsolidatedApplicationLog.swift b/ios/MullvadVPN/ConsolidatedApplicationLog.swift
index bd11fac1c9..b7e00b2ea9 100644
--- a/ios/MullvadVPN/ConsolidatedApplicationLog.swift
+++ b/ios/MullvadVPN/ConsolidatedApplicationLog.swift
@@ -33,9 +33,9 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
var errorDescription: String? {
switch self {
- case .logFileDoesNotExist(let path):
+ case let .logFileDoesNotExist(path):
return "Log file does not exist: \(path)."
- case .invalidLogFileURL(let url):
+ case let .invalidLogFileURL(url):
return "Invalid log file URL: \(url.absoluteString)."
}
}
@@ -47,13 +47,18 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
private var logs: [LogAttachment] = []
- init(redactCustomStrings: [String], redactContainerPathsForSecurityGroupIdentifiers securityGroupIdentifiers: [String]) {
- self.metadata = Self.makeMetadata()
+ init(
+ redactCustomStrings: [String],
+ redactContainerPathsForSecurityGroupIdentifiers securityGroupIdentifiers: [String]
+ ) {
+ metadata = Self.makeMetadata()
self.redactCustomStrings = redactCustomStrings
- applicationGroupContainers = securityGroupIdentifiers.compactMap { (securityGroupIdentifier) -> URL? in
- return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: securityGroupIdentifier)
- }
+ applicationGroupContainers = securityGroupIdentifiers
+ .compactMap { securityGroupIdentifier -> URL? in
+ return FileManager.default
+ .containerURL(forSecurityApplicationGroupIdentifier: securityGroupIdentifier)
+ }
}
func addLogFile(fileURL: URL, includeLogBackup: Bool) {
@@ -119,12 +124,13 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
private static func makeMetadata() -> Metadata {
let osVersion = ProcessInfo.processInfo.operatingSystemVersion
- let osVersionString = "iOS \(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
+ let osVersionString =
+ "iOS \(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
return [
- .id : UUID().uuidString,
+ .id: UUID().uuidString,
.productVersion: Bundle.main.productVersion,
- .os: osVersionString
+ .os: osVersionString,
]
}
@@ -142,59 +148,74 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
let data = fileHandle.readData(ofLength: Int(kLogMaxReadBytes))
let replacementCharacter = Character(UTF8.decode(UTF8.encodedReplacementCharacter))
- let lossyString = String(String(decoding: data, as: UTF8.self)
- .drop { ch in
- // Drop leading replacement characters produced when decoding data
- return ch == replacementCharacter
- })
+ let lossyString = String(
+ String(decoding: data, as: UTF8.self)
+ .drop { ch in
+ // Drop leading replacement characters produced when decoding data
+ return ch == replacementCharacter
+ }
+ )
return lossyString
}
private func redactCustomStrings(string: String) -> String {
- return redactCustomStrings.reduce(string) { (resultString, redact) -> String in
+ return redactCustomStrings.reduce(string) { resultString, redact -> String in
return resultString.replacingOccurrences(of: redact, with: kRedactedPlaceholder)
}
}
private func redact(string: String) -> String {
return [
- self.redactContainerPaths,
+ redactContainerPaths,
Self.redactAccountNumber,
Self.redactIPv4Address,
Self.redactIPv6Address,
- self.redactCustomStrings
- ].reduce(string) { (resultString, transform) -> String in
+ redactCustomStrings,
+ ].reduce(string) { resultString, transform -> String in
return transform(resultString)
}
}
private func redactContainerPaths(string: String) -> String {
- return applicationGroupContainers.reduce(string) { (resultString, containerURL) -> String in
- return resultString.replacingOccurrences(of: containerURL.path, with: kRedactedContainerPlaceholder)
+ return applicationGroupContainers.reduce(string) { resultString, containerURL -> String in
+ return resultString.replacingOccurrences(
+ of: containerURL.path,
+ with: kRedactedContainerPlaceholder
+ )
}
}
private static func redactAccountNumber(string: String) -> String {
- return redact(regularExpression: try! NSRegularExpression(pattern: #"\d{16}"#),
- string: string,
- replacementString: kRedactedAccountPlaceholder)
+ return redact(
+ regularExpression: try! NSRegularExpression(pattern: #"\d{16}"#),
+ string: string,
+ replacementString: kRedactedAccountPlaceholder
+ )
}
private static func redactIPv4Address(string: String) -> String {
- return redact(regularExpression: NSRegularExpression.ipv4RegularExpression,
- string: string,
- replacementString: kRedactedPlaceholder)
+ return redact(
+ regularExpression: NSRegularExpression.ipv4RegularExpression,
+ string: string,
+ replacementString: kRedactedPlaceholder
+ )
}
private static func redactIPv6Address(string: String) -> String {
- return redact(regularExpression: NSRegularExpression.ipv6RegularExpression,
- string: string,
- replacementString: kRedactedPlaceholder)
+ return redact(
+ regularExpression: NSRegularExpression.ipv6RegularExpression,
+ string: string,
+ replacementString: kRedactedPlaceholder
+ )
}
- private static func redact(regularExpression: NSRegularExpression, string: String, replacementString: String) -> String {
- let nsRange = NSRange((string.startIndex..<string.endIndex), in: string)
+ private static func redact(
+ regularExpression: NSRegularExpression,
+ string: String,
+ replacementString: String
+ ) -> String {
+ let nsRange = NSRange(string.startIndex ..< string.endIndex, in: string)
let template = NSRegularExpression.escapedTemplate(for: replacementString)
return regularExpression.stringByReplacingMatches(
@@ -204,5 +225,4 @@ class ConsolidatedApplicationLog: TextOutputStreamable {
withTemplate: template
)
}
-
}
diff --git a/ios/MullvadVPN/CustomDateComponentsFormatting.swift b/ios/MullvadVPN/CustomDateComponentsFormatting.swift
index d9c12dabff..07c2867ab2 100644
--- a/ios/MullvadVPN/CustomDateComponentsFormatting.swift
+++ b/ios/MullvadVPN/CustomDateComponentsFormatting.swift
@@ -11,7 +11,6 @@ import Foundation
enum CustomDateComponentsFormatting {}
extension CustomDateComponentsFormatting {
-
/// Format a duration between the given dates returning a string that only contains one unit.
///
/// The behaviour of that method differs from `DateComponentsFormatter`:
@@ -25,8 +24,8 @@ extension CustomDateComponentsFormatting {
from start: Date,
to end: Date,
calendar: Calendar = Calendar.current,
- unitsStyle: DateComponentsFormatter.UnitsStyle) -> String?
- {
+ unitsStyle: DateComponentsFormatter.UnitsStyle
+ ) -> String? {
let formatter = DateComponentsFormatter()
formatter.calendar = calendar
formatter.unitsStyle = unitsStyle
@@ -41,16 +40,16 @@ extension CustomDateComponentsFormatting {
let minutes = dateComponents.minute ?? 0
let seconds = dateComponents.second ?? 0
- if days == 0 && hours == 0 && minutes == 0 && seconds < 60 {
+ if days == 0, hours == 0, minutes == 0, seconds < 60 {
return NSLocalizedString(
"LESS_THAN_ONE_MINUTE",
tableName: "CustomDateComponentsFormatting",
value: "Less than a minute",
comment: "Phrase used for less than 1 minute duration."
)
- } else if days == 0 && hours == 23 && minutes >= 30 {
+ } else if days == 0, hours == 23, minutes >= 30 {
return formatter.string(from: DateComponents(calendar: calendar, day: 1))
- } else if days >= 1 && days <= 90 {
+ } else if days >= 1, days <= 90 {
formatter.allowedUnits = [.day]
return formatter.string(from: dateComponents)
} else {
diff --git a/ios/MullvadVPN/CustomNavigationBar.swift b/ios/MullvadVPN/CustomNavigationBar.swift
index 7f27dbe7c6..5d56f92e5b 100644
--- a/ios/MullvadVPN/CustomNavigationBar.swift
+++ b/ios/MullvadVPN/CustomNavigationBar.swift
@@ -10,36 +10,46 @@ import UIKit
class CustomNavigationBar: UINavigationBar {
private static let titleTextAttributes: [NSAttributedString.Key: Any] = [
- .foregroundColor: UIColor.NavigationBar.titleColor
+ .foregroundColor: UIColor.NavigationBar.titleColor,
]
private static let backButtonTitlePositionOffset = UIOffset(horizontal: 4, vertical: 0)
private static let backButtonTitleTextAttributes: [NSAttributedString.Key: Any] = [
- .foregroundColor: UIColor.NavigationBar.backButtonTitleColor
+ .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)
+ 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(UIColor.NavigationBar.backButtonIndicatorColor, renderingMode: .alwaysOriginal)
+ .backport_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
var titleLabelBottomInset: CGFloat {
// Go two levels deep only
- let subviewsToExamine = subviews.flatMap { (view) -> [UIView] in
+ let subviewsToExamine = subviews.flatMap { view -> [UIView] in
return [view] + view.subviews
}
- let titleLabel = subviewsToExamine.first { (view) -> Bool in
+ let titleLabel = subviewsToExamine.first { view -> Bool in
return view is UILabel
}
@@ -109,14 +119,19 @@ class CustomNavigationBar: UINavigationBar {
navigationBarAppearance.backButtonAppearance = backButtonAppearance
if #available(iOS 14, *) {
- navigationBarAppearance.setBackIndicatorImage(customBackIndicatorImage, transitionMaskImage: customBackIndicatorTransitionMask)
+ navigationBarAppearance.setBackIndicatorImage(
+ customBackIndicatorImage,
+ transitionMaskImage: customBackIndicatorTransitionMask
+ )
} else {
// Bug: on iOS 13 setBackIndicatorImage accepts parameters in backward order
// https://stackoverflow.com/a/58171229/351305
- navigationBarAppearance.setBackIndicatorImage(customBackIndicatorTransitionMask, transitionMaskImage: customBackIndicatorImage)
+ navigationBarAppearance.setBackIndicatorImage(
+ customBackIndicatorTransitionMask,
+ transitionMaskImage: customBackIndicatorImage
+ )
}
return navigationBarAppearance
}
-
}
diff --git a/ios/MullvadVPN/CustomNavigationController.swift b/ios/MullvadVPN/CustomNavigationController.swift
index 2f7d29f289..a19136b0c8 100644
--- a/ios/MullvadVPN/CustomNavigationController.swift
+++ b/ios/MullvadVPN/CustomNavigationController.swift
@@ -15,11 +15,11 @@ enum NavigationPopTrigger {
}
protocol ConditionalNavigation: AnyObject {
- func shouldPopNavigationItem(_ navigationItem: UINavigationItem, trigger: NavigationPopTrigger) -> Bool
+ func shouldPopNavigationItem(_ navigationItem: UINavigationItem, trigger: NavigationPopTrigger)
+ -> Bool
}
class CustomNavigationController: UINavigationController, UINavigationBarDelegate {
-
private static let classInit: Void = {
swizzleMethod(
aClass: CustomNavigationController.self,
@@ -35,13 +35,19 @@ class CustomNavigationController: UINavigationController, UINavigationBarDelegat
_ = Self.classInit
- popGestureRecognizerDelegate = CustomPopGestureRecognizerDelegate(navigationController: self, systemGestureRecognizerDelegate: interactivePopGestureRecognizer?.delegate)
+ popGestureRecognizerDelegate = CustomPopGestureRecognizerDelegate(
+ navigationController: self,
+ systemGestureRecognizerDelegate: interactivePopGestureRecognizer?.delegate
+ )
// Replace the system interactive gesture recognizer
interactivePopGestureRecognizer?.delegate = popGestureRecognizerDelegate
}
- @objc dynamic func customNavigationController_navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
+ @objc dynamic func customNavigationController_navigationBar(
+ _ navigationBar: UINavigationBar,
+ shouldPop item: UINavigationItem
+ ) -> Bool {
var shouldPop = true
if let conformingViewController = topViewController as? ConditionalNavigation {
@@ -59,11 +65,13 @@ class CustomNavigationController: UINavigationController, UINavigationBarDelegat
}
private class CustomPopGestureRecognizerDelegate: NSObject, UIGestureRecognizerDelegate {
-
private let systemGestureRecognizerDelegate: UIGestureRecognizerDelegate?
private weak var navigationController: UINavigationController?
- init(navigationController: UINavigationController, systemGestureRecognizerDelegate: UIGestureRecognizerDelegate?) {
+ init(
+ navigationController: UINavigationController,
+ systemGestureRecognizerDelegate: UIGestureRecognizerDelegate?
+ ) {
self.navigationController = navigationController
self.systemGestureRecognizerDelegate = systemGestureRecognizerDelegate
}
@@ -89,14 +97,20 @@ private class CustomPopGestureRecognizerDelegate: NSObject, UIGestureRecognizerD
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
- let shouldBegin = systemGestureRecognizerDelegate?.gestureRecognizerShouldBegin?(gestureRecognizer) ?? true
+ let shouldBegin = systemGestureRecognizerDelegate?
+ .gestureRecognizerShouldBegin?(gestureRecognizer) ?? true
guard let navigationController = navigationController,
- let topItem = navigationController.navigationBar.topItem,
- let conformingViewController = navigationController.topViewController as? ConditionalNavigation else {
- return shouldBegin
+ let topItem = navigationController.navigationBar.topItem,
+ let conformingViewController = navigationController
+ .topViewController as? ConditionalNavigation
+ else {
+ return shouldBegin
}
- return shouldBegin && conformingViewController.shouldPopNavigationItem(topItem, trigger: .interactiveGesture)
+ return shouldBegin && conformingViewController.shouldPopNavigationItem(
+ topItem,
+ trigger: .interactiveGesture
+ )
}
}
diff --git a/ios/MullvadVPN/CustomSplitViewController.swift b/ios/MullvadVPN/CustomSplitViewController.swift
index 662eef869b..752eae49e9 100644
--- a/ios/MullvadVPN/CustomSplitViewController.swift
+++ b/ios/MullvadVPN/CustomSplitViewController.swift
@@ -9,7 +9,6 @@
import UIKit
class CustomSplitViewController: UISplitViewController, RootContainment {
-
var preferredHeaderBarPresentation: HeaderBarPresentation {
for case let viewController as RootContainment in viewControllers {
return viewController.preferredHeaderBarPresentation
@@ -60,11 +59,11 @@ class CustomSplitViewController: UISplitViewController, RootContainment {
}
private var dividerView: UIView? {
- let subviews = view.subviews.flatMap { (view) -> [UIView] in
+ let subviews = view.subviews.flatMap { view -> [UIView] in
return [view] + view.subviews
}
- return subviews.first { (view) -> Bool in
+ return subviews.first { view -> Bool in
return view.description.hasPrefix("<UIPanelBorderView")
}
}
@@ -75,18 +74,23 @@ class CustomSplitViewController: UISplitViewController, RootContainment {
dividerView?.backgroundColor = dividerColor
}
- override func overrideTraitCollection(forChild childViewController: UIViewController) -> UITraitCollection? {
- guard let traitCollection = super.overrideTraitCollection(forChild: childViewController) else { return nil }
+ override func overrideTraitCollection(forChild childViewController: UIViewController)
+ -> UITraitCollection?
+ {
+ guard let traitCollection = super.overrideTraitCollection(forChild: childViewController)
+ else { return nil }
// Pass the split controller's horizontal size class to the primary controller when split
// view is expanded.
- if !self.isCollapsed, childViewController == self.viewControllers.last {
- let sizeOverrideTraitCollection = UITraitCollection(horizontalSizeClass: self.traitCollection.horizontalSizeClass)
+ if !isCollapsed, childViewController == viewControllers.last {
+ let sizeOverrideTraitCollection = UITraitCollection(
+ horizontalSizeClass: self
+ .traitCollection.horizontalSizeClass
+ )
return UITraitCollection(traitsFrom: [traitCollection, sizeOverrideTraitCollection])
} else {
return traitCollection
}
}
-
}
diff --git a/ios/MullvadVPN/CustomSwitch.swift b/ios/MullvadVPN/CustomSwitch.swift
index d0eb29aeca..fb3d5bc3eb 100644
--- a/ios/MullvadVPN/CustomSwitch.swift
+++ b/ios/MullvadVPN/CustomSwitch.swift
@@ -9,16 +9,15 @@
import UIKit
class CustomSwitch: UISwitch {
-
/// Returns the private `UISwitch` background view
private var backgroundView: UIView? {
// Go two levels deep only
- let subviewsToExamine = subviews.flatMap { (view) -> [UIView] in
+ let subviewsToExamine = subviews.flatMap { view -> [UIView] in
return [view] + view.subviews
}
// Find the first subview that has background color set.
- let backgroundView = subviewsToExamine.first { (subview) in
+ let backgroundView = subviewsToExamine.first { subview in
return subview.backgroundColor != nil
}
@@ -35,7 +34,7 @@ class CustomSwitch: UISwitch {
overrideUserInterfaceStyle = .light
}
- updateThumbColor(isOn: self.isOn, animated: false)
+ updateThumbColor(isOn: isOn, animated: false)
addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged)
}
diff --git a/ios/MullvadVPN/CustomSwitchContainer.swift b/ios/MullvadVPN/CustomSwitchContainer.swift
index 7acafc4495..55316f2929 100644
--- a/ios/MullvadVPN/CustomSwitchContainer.swift
+++ b/ios/MullvadVPN/CustomSwitchContainer.swift
@@ -50,8 +50,8 @@ class CustomSwitchContainer: UIView {
control.sizeToFit()
sizeToFit()
- borderShape.cornerRadius = self.bounds.height * 0.5
- borderShape.frame = self.bounds
+ borderShape.cornerRadius = bounds.height * 0.5
+ borderShape.frame = bounds
updateBorderOpacity()
}
@@ -83,5 +83,4 @@ class CustomSwitchContainer: UIView {
CATransaction.commit()
}
-
}
diff --git a/ios/MullvadVPN/CustomTextField.swift b/ios/MullvadVPN/CustomTextField.swift
index 9c400f4720..d6813bfcf2 100644
--- a/ios/MullvadVPN/CustomTextField.swift
+++ b/ios/MullvadVPN/CustomTextField.swift
@@ -10,7 +10,6 @@ import Foundation
import UIKit
class CustomTextField: UITextField {
-
var cornerRadius: CGFloat = UIMetrics.controlCornerRadius {
didSet {
layer.cornerRadius = cornerRadius
@@ -23,7 +22,7 @@ class CustomTextField: UITextField {
}
}
- var placeholderTextColor: UIColor = UIColor.TextField.placeholderTextColor {
+ var placeholderTextColor = UIColor.TextField.placeholderTextColor {
didSet {
updatePlaceholderTextColor()
}
diff --git a/ios/MullvadVPN/CustomTextView.swift b/ios/MullvadVPN/CustomTextView.swift
index aed22fe07e..d3dffe8e79 100644
--- a/ios/MullvadVPN/CustomTextView.swift
+++ b/ios/MullvadVPN/CustomTextView.swift
@@ -11,7 +11,7 @@ import UIKit
class CustomTextView: UITextView {
private static let textViewCornerRadius: CGFloat = 4
- var roundCorners: Bool = true {
+ var roundCorners = true {
didSet {
layer.cornerRadius = roundCorners ? Self.textViewCornerRadius : 0
}
@@ -41,7 +41,7 @@ class CustomTextView: UITextView {
override var font: UIFont? {
didSet {
- placeholderTextLabel.font = self.font ?? UIFont.preferredFont(forTextStyle: .body)
+ placeholderTextLabel.font = font ?? UIFont.preferredFont(forTextStyle: .body)
}
}
@@ -74,7 +74,10 @@ class CustomTextView: UITextView {
}
get {
if roundCorners {
- return UIBezierPath(roundedRect: accessibilityFrame, cornerRadius: Self.textViewCornerRadius)
+ return UIBezierPath(
+ roundedRect: accessibilityFrame,
+ cornerRadius: Self.textViewCornerRadius
+ )
} else {
return UIBezierPath(rect: accessibilityFrame)
}
@@ -97,9 +100,12 @@ class CustomTextView: UITextView {
// Create placeholder constraints
placeholderConstraints = [
placeholderTextLabel.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
- placeholderTextLabel.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
- placeholderTextLabel.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
- placeholderTextLabel.bottomAnchor.constraint(lessThanOrEqualTo: safeAreaLayoutGuide.bottomAnchor),
+ placeholderTextLabel.leadingAnchor
+ .constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
+ placeholderTextLabel.trailingAnchor
+ .constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
+ placeholderTextLabel.bottomAnchor
+ .constraint(lessThanOrEqualTo: safeAreaLayoutGuide.bottomAnchor),
]
NSLayoutConstraint.activate(placeholderConstraints)
@@ -117,8 +123,9 @@ class CustomTextView: UITextView {
notificationObserver = NotificationCenter.default.addObserver(
forName: NSTextStorage.didProcessEditingNotification,
object: textStorage,
- queue: OperationQueue.main) { [weak self] (note) in
- self?.updatePlaceholderVisibility()
+ queue: OperationQueue.main
+ ) { [weak self] note in
+ self?.updatePlaceholderVisibility()
}
updatePlaceholderVisibility()
@@ -158,5 +165,4 @@ class CustomTextView: UITextView {
private func updatePlaceholderVisibility() {
placeholderTextLabel.isHidden = textStorage.length > 0
}
-
}
diff --git a/ios/MullvadVPN/DNSSettings.swift b/ios/MullvadVPN/DNSSettings.swift
index f841b6cb1b..e204a7f60b 100644
--- a/ios/MullvadVPN/DNSSettings.swift
+++ b/ios/MullvadVPN/DNSSettings.swift
@@ -56,7 +56,7 @@ struct DNSSettings: Codable, Equatable {
var blockingOptions: DNSBlockingOptions = []
/// Enable custom DNS.
- var enableCustomDNS: Bool = false
+ var enableCustomDNS = false
/// Custom DNS domains.
var customDNSDomains: [AnyIPAddress] = []
@@ -82,23 +82,38 @@ struct DNSSettings: Codable, Equatable {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Added in 2022.1
- if let storedBlockingOptions = try container.decodeIfPresent(DNSBlockingOptions.self, forKey: .blockingOptions) {
+ if let storedBlockingOptions = try container.decodeIfPresent(
+ DNSBlockingOptions.self,
+ forKey: .blockingOptions
+ ) {
blockingOptions = storedBlockingOptions
}
- if let storedBlockAdvertising = try container.decodeIfPresent(Bool.self, forKey: .blockAdvertising), storedBlockAdvertising {
+ if let storedBlockAdvertising = try container.decodeIfPresent(
+ Bool.self,
+ forKey: .blockAdvertising
+ ), storedBlockAdvertising {
blockingOptions.insert(.blockAdvertising)
}
- if let storedBlockTracking = try container.decodeIfPresent(Bool.self, forKey: .blockTracking), storedBlockTracking {
+ if let storedBlockTracking = try container.decodeIfPresent(
+ Bool.self,
+ forKey: .blockTracking
+ ), storedBlockTracking {
blockingOptions.insert(.blockTracking)
}
- if let storedEnableCustomDNS = try container.decodeIfPresent(Bool.self, forKey: .enableCustomDNS) {
+ if let storedEnableCustomDNS = try container.decodeIfPresent(
+ Bool.self,
+ forKey: .enableCustomDNS
+ ) {
enableCustomDNS = storedEnableCustomDNS
}
- if let storedCustomDNSDomains = try container.decodeIfPresent([AnyIPAddress].self, forKey: .customDNSDomains) {
+ if let storedCustomDNSDomains = try container.decodeIfPresent(
+ [AnyIPAddress].self,
+ forKey: .customDNSDomains
+ ) {
customDNSDomains = storedCustomDNSDomains
}
}
diff --git a/ios/MullvadVPN/DataSourceSnapshot.swift b/ios/MullvadVPN/DataSourceSnapshot.swift
index 19b6043aa1..6e19708776 100644
--- a/ios/MullvadVPN/DataSourceSnapshot.swift
+++ b/ios/MullvadVPN/DataSourceSnapshot.swift
@@ -48,7 +48,10 @@ struct DataSourceSnapshot<Section: Hashable, Item: Hashable> {
let newItemRange = (itemRange.startIndex ..< newEndIndex)
sectionToItemMapping[sectionIndex] = newItemRange
- orderedItems.insert(uniqueItemsToAppend.array, at: IndexSet(integersIn: oldEndIndex..<newEndIndex))
+ orderedItems.insert(
+ uniqueItemsToAppend.array,
+ at: IndexSet(integersIn: oldEndIndex ..< newEndIndex)
+ )
offsetItemRange(inSectionsAfter: sectionIndex, by: uniqueItemsToAppend.count)
}
@@ -56,8 +59,8 @@ struct DataSourceSnapshot<Section: Hashable, Item: Hashable> {
mutating func appendSections(_ newSections: [Section]) {
let lastSectionRange = sectionToItemMapping.last
let emptyRange = lastSectionRange.flatMap { range in
- return (range.upperBound..<range.upperBound)
- } ?? (0..<0)
+ return (range.upperBound ..< range.upperBound)
+ } ?? (0 ..< 0)
let uniqueNewSections = NSOrderedSet(array: newSections)
@@ -193,21 +196,21 @@ extension DataSourceSnapshot {
var debugDescription: String {
switch self {
- case .insert(let indexPath):
+ case let .insert(indexPath):
return "insert \(indexPath)"
- case .delete(let indexPath):
+ case let .delete(indexPath):
return "delete \(indexPath)"
- case .move(let source, let target):
+ case let .move(source, target):
return "move from \(source) to \(target)"
- case .reload(let indexPath):
+ case let .reload(indexPath):
return "reload \(indexPath)"
- case .reconfigure(let indexPath):
+ case let .reconfigure(indexPath):
return "reconfigure \(indexPath)"
}
}
func breakMoveOntoInsertionDeletion() -> [Change] {
- if case .move(let fromIndexPath, let toIndexPath) = self {
+ if case let .move(fromIndexPath, toIndexPath) = self {
return [.delete(fromIndexPath), .insert(toIndexPath)]
} else {
return [self]
@@ -233,7 +236,7 @@ extension DataSourceSnapshot {
// Guard against recording the `.move` twice when exchanging two adjacent items.
let isSwappingTwoAdjacentItems = changes.contains { otherChange in
- if case .move(let fromIndexPath, let toIndexPath) = otherChange {
+ if case let .move(fromIndexPath, toIndexPath) = otherChange {
let itemDistance = abs(oldIndexPath.row - fromIndexPath.row)
return oldIndexPath == toIndexPath && newIndexPath == fromIndexPath &&
@@ -291,29 +294,34 @@ extension DataSourceSnapshot {
.sorted(by: Self.changeSortPredicate)
for sourceChange in changes {
- guard case .move(let sourceIndexPath, let targetIndexPath) = sourceChange else {
+ guard case let .move(sourceIndexPath, targetIndexPath) = sourceChange else {
newChanges.append(sourceChange)
continue
}
// Replay all changes to compute the item's index path, ignoring the changes associated with the current
// change.
- let inferredIndexPath = sortedChangesWithoutMoves.reduce(into: sourceIndexPath) { inferredIndexPath, otherChange in
- switch otherChange {
- case .insert(let insertedIndexPath) where insertedIndexPath != targetIndexPath:
- if inferredIndexPath.row >= insertedIndexPath.row, inferredIndexPath.section == insertedIndexPath.section {
- inferredIndexPath.row += 1
- }
+ let inferredIndexPath = sortedChangesWithoutMoves
+ .reduce(into: sourceIndexPath) { inferredIndexPath, otherChange in
+ switch otherChange {
+ case let .insert(insertedIndexPath) where insertedIndexPath != targetIndexPath:
+ if inferredIndexPath.row >= insertedIndexPath.row,
+ inferredIndexPath.section == insertedIndexPath.section
+ {
+ inferredIndexPath.row += 1
+ }
- case .delete(let deletedIndexPath) where deletedIndexPath != sourceIndexPath:
- if inferredIndexPath.row > deletedIndexPath.row, inferredIndexPath.section == deletedIndexPath.section {
- inferredIndexPath.row -= 1
- }
+ case let .delete(deletedIndexPath) where deletedIndexPath != sourceIndexPath:
+ if inferredIndexPath.row > deletedIndexPath.row,
+ inferredIndexPath.section == deletedIndexPath.section
+ {
+ inferredIndexPath.row -= 1
+ }
- default:
- break
+ default:
+ break
+ }
}
- }
// Discard the change if the index path, produced after replaying other changes, matches the target index
// path.
@@ -333,19 +341,19 @@ extension DataSourceSnapshot {
/// Reload, reconfigure: ascending
private static func changeSortPredicate(_ lhs: Change, _ rhs: Change) -> Bool {
switch (lhs, rhs) {
- case (.insert(let lhsIndexPath), .insert(let rhsIndexPath)):
+ case let (.insert(lhsIndexPath), .insert(rhsIndexPath)):
return lhsIndexPath < rhsIndexPath
- case (.delete(let lhsIndexPath), .delete(let rhsIndexPath)):
+ case let (.delete(lhsIndexPath), .delete(rhsIndexPath)):
return lhsIndexPath > rhsIndexPath
- case (.reload(let lhsIndexPath), .reload(let rhsIndexPath)):
+ case let (.reload(lhsIndexPath), .reload(rhsIndexPath)):
return lhsIndexPath < rhsIndexPath
- case (.reconfigure(let lhsIndexPath), .reconfigure(let rhsIndexPath)):
+ case let (.reconfigure(lhsIndexPath), .reconfigure(rhsIndexPath)):
return lhsIndexPath < rhsIndexPath
- case (let lhs, let rhs):
+ case let (lhs, rhs):
return lhs.sortOrder < rhs.sortOrder
}
}
@@ -358,20 +366,20 @@ extension DataSourceSnapshot {
for change in changes {
switch change {
- case .insert(let indexPath):
+ case let .insert(indexPath):
indexPathsToInsert.append(indexPath)
- case .delete(let indexPath):
+ case let .delete(indexPath):
indexPathsToDelete.append(indexPath)
case .move:
// Moves are broken down onto insert and delete changes at this point.
break
- case .reload(let indexPath):
+ case let .reload(indexPath):
indexPathsToReload.append(indexPath)
- case .reconfigure(let indexPath):
+ case let .reconfigure(indexPath):
indexPathsToReconfigure.append(indexPath)
}
}
@@ -425,7 +433,11 @@ struct DataSnapshotDifference: CustomDebugStringConvertible {
return s
}
- func apply(to tableView: UITableView, animateDifferences: Bool, completion: ((Bool) -> Void)? = nil) {
+ func apply(
+ to tableView: UITableView,
+ animateDifferences: Bool,
+ completion: ((Bool) -> Void)? = nil
+ ) {
let animation: UITableView.RowAnimation = animateDifferences ? .automatic : .none
tableView.performBatchUpdates({
@@ -456,8 +468,7 @@ struct DataSnapshotDifference: CustomDebugStringConvertible {
configuration: StackViewApplyDataSnapshotConfiguration,
animateDifferences: Bool,
completion: ((Bool) -> Void)? = nil
- )
- {
+ ) {
let viewsToRemove = indexPathsToDelete.map { indexPath in
return stackView.arrangedSubviews[indexPath.row]
}
diff --git a/ios/MullvadVPN/DeviceManagementContentView.swift b/ios/MullvadVPN/DeviceManagementContentView.swift
index f62013bef0..abff4306b2 100644
--- a/ios/MullvadVPN/DeviceManagementContentView.swift
+++ b/ios/MullvadVPN/DeviceManagementContentView.swift
@@ -83,7 +83,7 @@ class DeviceManagementContentView: UIView {
return stackView
}()
- var canContinue: Bool = false {
+ var canContinue = false {
didSet {
updateView()
}
@@ -133,7 +133,7 @@ class DeviceManagementContentView: UIView {
spacer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
let subviewsToAdd = [
- statusImageView, titleLabel, messageLabel, deviceStackView, spacer, buttonStackView
+ statusImageView, titleLabel, messageLabel, deviceStackView, spacer, buttonStackView,
]
for subview in subviewsToAdd {
addSubview(subview)
@@ -168,7 +168,7 @@ class DeviceManagementContentView: UIView {
buttonStackView.topAnchor.constraint(equalTo: spacer.bottomAnchor),
buttonStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
buttonStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
])
}
@@ -214,9 +214,9 @@ class DeviceManagementContentView: UIView {
"LOGOUT_DEVICES_MESSAGE",
tableName: "DeviceManagement",
value: """
- Please log out of at least one by removing it from the list below. You can find \
- the corresponding device name under the device’s Account settings.
- """,
+ Please log out of at least one by removing it from the list below. You can find \
+ the corresponding device name under the device’s Account settings.
+ """,
comment: ""
)
}
diff --git a/ios/MullvadVPN/DeviceManagementInteractor.swift b/ios/MullvadVPN/DeviceManagementInteractor.swift
index 08d7d744be..1890799221 100644
--- a/ios/MullvadVPN/DeviceManagementInteractor.swift
+++ b/ios/MullvadVPN/DeviceManagementInteractor.swift
@@ -17,7 +17,10 @@ class DeviceManagementInteractor {
}
@discardableResult
- func getDevices(_ completionHandler: @escaping (OperationCompletion<[REST.Device], Error>) -> Void) -> Cancellable {
+ func getDevices(
+ _ completionHandler: @escaping (OperationCompletion<[REST.Device], Error>)
+ -> Void
+ ) -> Cancellable {
return devicesProxy.getDevices(
accountNumber: accountNumber,
retryStrategy: .default
@@ -27,7 +30,10 @@ class DeviceManagementInteractor {
}
@discardableResult
- func deleteDevice(_ identifier: String, completionHandler: @escaping (OperationCompletion<Bool, Error>) -> Void) -> Cancellable {
+ func deleteDevice(
+ _ identifier: String,
+ completionHandler: @escaping (OperationCompletion<Bool, Error>) -> Void
+ ) -> Cancellable {
return devicesProxy.deleteDevice(
accountNumber: accountNumber,
identifier: identifier,
diff --git a/ios/MullvadVPN/DeviceManagementViewController.swift b/ios/MullvadVPN/DeviceManagementViewController.swift
index 9db683cff4..128e1c6ab4 100644
--- a/ios/MullvadVPN/DeviceManagementViewController.swift
+++ b/ios/MullvadVPN/DeviceManagementViewController.swift
@@ -6,8 +6,8 @@
// Copyright © 2022 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
protocol DeviceManagementViewControllerDelegate: AnyObject {
func deviceManagementViewControllerDidFinish(_ controller: DeviceManagementViewController)
@@ -94,7 +94,10 @@ class DeviceManagementViewController: UIViewController, RootContainment {
])
}
- func fetchDevices(animateUpdates: Bool, completionHandler: ((OperationCompletion<Void, Error>) -> Void)? = nil) {
+ func fetchDevices(
+ animateUpdates: Bool,
+ completionHandler: ((OperationCompletion<Void, Error>) -> Void)? = nil
+ ) {
interactor.getDevices { [weak self] completion in
guard let self = self else { return }
@@ -151,7 +154,7 @@ class DeviceManagementViewController: UIViewController, RootContainment {
}
private func getErrorDescription(_ error: Error) -> String {
- if case .network(let urlError) = error as? REST.Error {
+ if case let .network(urlError) = error as? REST.Error {
return urlError.localizedDescription
} else {
return error.localizedDescription
@@ -223,7 +226,7 @@ class DeviceManagementViewController: UIViewController, RootContainment {
handler: { _ in
completion(true)
}
- )
+ ),
]
for action in actions {
@@ -243,7 +246,7 @@ class DeviceManagementViewController: UIViewController, RootContainment {
completionHandler(completion.error)
}
- case .failure(let error):
+ case let .failure(error):
self.logger.error(
chainedError: AnyChainedError(error),
message: "Failed to delete device."
diff --git a/ios/MullvadVPN/DeviceRowView.swift b/ios/MullvadVPN/DeviceRowView.swift
index bca1830ccd..c35f2f78db 100644
--- a/ios/MullvadVPN/DeviceRowView.swift
+++ b/ios/MullvadVPN/DeviceRowView.swift
@@ -45,7 +45,7 @@ class DeviceRowView: UIView {
return button
}()
- var showsActivityIndicator: Bool = false {
+ var showsActivityIndicator = false {
didSet {
removeButton.isHidden = showsActivityIndicator
diff --git a/ios/MullvadVPN/DisconnectSplitButton.swift b/ios/MullvadVPN/DisconnectSplitButton.swift
index 4a7f18a369..59e807cfa0 100644
--- a/ios/MullvadVPN/DisconnectSplitButton.swift
+++ b/ios/MullvadVPN/DisconnectSplitButton.swift
@@ -10,10 +10,9 @@ import Foundation
import UIKit
class DisconnectSplitButton: UIView {
-
private var secondaryButtonSize: CGSize {
// TODO: make it less hardcoded
- switch self.traitCollection.userInterfaceIdiom {
+ switch traitCollection.userInterfaceIdiom {
case .phone:
return CGSize(width: 42, height: 42)
case .pad:
@@ -42,11 +41,15 @@ class DisconnectSplitButton: UIView {
stackView.alignment = .fill
stackView.spacing = 1
- secondaryButton.setImage(UIImage(named: "IconReload")?.imageFlippedForRightToLeftLayoutDirection(), for: .normal)
+ secondaryButton.setImage(
+ UIImage(named: "IconReload")?.imageFlippedForRightToLeftLayoutDirection(),
+ for: .normal
+ )
primaryButton.overrideContentEdgeInsets = true
secondaryButtonWidthConstraint = secondaryButton.widthAnchor.constraint(equalToConstant: 0)
- secondaryButtonHeightConstraint = secondaryButton.heightAnchor.constraint(equalToConstant: 0)
+ secondaryButtonHeightConstraint = secondaryButton.heightAnchor
+ .constraint(equalToConstant: 0)
super.init(frame: .zero)
@@ -59,7 +62,7 @@ class DisconnectSplitButton: UIView {
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
secondaryButtonWidthConstraint,
- secondaryButtonHeightConstraint
+ secondaryButtonHeightConstraint,
])
updateTraitConstraints()
@@ -78,7 +81,7 @@ class DisconnectSplitButton: UIView {
}
private func updateTraitConstraints() {
- let newSize = self.secondaryButtonSize
+ let newSize = secondaryButtonSize
secondaryButtonWidthConstraint.constant = newSize.width
secondaryButtonHeightConstraint.constant = newSize.height
adjustTitleLabelPosition()
@@ -87,7 +90,7 @@ class DisconnectSplitButton: UIView {
private func adjustTitleLabelPosition() {
var contentInsets = primaryButton.defaultContentInsets
- let offset = stackView.spacing + self.secondaryButtonSize.width
+ let offset = stackView.spacing + secondaryButtonSize.width
if case .leftToRight = effectiveUserInterfaceLayoutDirection {
contentInsets.left = offset
diff --git a/ios/MullvadVPN/DisplayChainedError.swift b/ios/MullvadVPN/DisplayChainedError.swift
index cb0ab32a9d..15dcf930ce 100644
--- a/ios/MullvadVPN/DisplayChainedError.swift
+++ b/ios/MullvadVPN/DisplayChainedError.swift
@@ -16,7 +16,7 @@ protocol DisplayChainedError {
extension REST.Error: DisplayChainedError {
var errorChainDescription: String? {
switch self {
- case .network(let urlError):
+ case let .network(urlError):
return String(
format: NSLocalizedString(
"NETWORK_ERROR",
@@ -26,7 +26,7 @@ extension REST.Error: DisplayChainedError {
),
urlError.localizedDescription
)
- case .unhandledResponse(let statusCode, let serverResponse):
+ case let .unhandledResponse(statusCode, serverResponse):
return String(
format: NSLocalizedString(
"SERVER_ERROR",
@@ -57,7 +57,7 @@ extension REST.Error: DisplayChainedError {
extension SKError: LocalizedError {
public var errorDescription: String? {
- switch self.code {
+ switch code {
case .unknown:
return NSLocalizedString(
"UNKNOWN_ERROR",
@@ -94,7 +94,7 @@ extension SKError: LocalizedError {
comment: ""
)
default:
- return self.localizedDescription
+ return localizedDescription
}
}
}
@@ -110,7 +110,7 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
comment: ""
)
- case .validateAccount(let restError):
+ case let .validateAccount(restError):
let reason = restError.errorChainDescription ?? ""
if restError.compareErrorCode(.invalidAccount) {
@@ -135,10 +135,11 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
)
}
- case .readReceipt(let readReceiptError):
+ case let .readReceipt(readReceiptError):
switch readReceiptError {
- case .refresh(let storeError):
- let skErrorMessage = (storeError as? SKError)?.errorDescription ?? storeError.localizedDescription
+ case let .refresh(storeError):
+ let skErrorMessage = (storeError as? SKError)?.errorDescription ?? storeError
+ .localizedDescription
return String(
format: NSLocalizedString(
@@ -149,7 +150,7 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
),
skErrorMessage
)
- case .io(let ioError):
+ case let .io(ioError):
return String(
format: NSLocalizedString(
"READ_RECEIPT_ERROR",
@@ -168,7 +169,7 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
)
}
- case .sendReceipt(let restError):
+ case let .sendReceipt(restError):
let reason = restError.errorChainDescription ?? ""
let errorFormat = NSLocalizedString(
"SEND_RECEIPT_ERROR",
@@ -187,7 +188,7 @@ extension AppStorePaymentManager.Error: DisplayChainedError {
errorString.append(recoverySuggestion)
return errorString
- case .storePayment(let storeError):
+ case let .storePayment(storeError):
return (storeError as? SKError)?.errorDescription ?? storeError.localizedDescription
}
}
diff --git a/ios/MullvadVPN/EmptyTableViewHeaderFooterView.swift b/ios/MullvadVPN/EmptyTableViewHeaderFooterView.swift
index 78c30b5e15..46b88f78ed 100644
--- a/ios/MullvadVPN/EmptyTableViewHeaderFooterView.swift
+++ b/ios/MullvadVPN/EmptyTableViewHeaderFooterView.swift
@@ -9,13 +9,12 @@
import UIKit
class EmptyTableViewHeaderFooterView: UITableViewHeaderFooterView {
-
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
- self.textLabel?.isHidden = true
- self.contentView.backgroundColor = .clear
- self.backgroundView?.backgroundColor = .clear
+ textLabel?.isHidden = true
+ contentView.backgroundColor = .clear
+ backgroundView?.backgroundColor = .clear
}
required init?(coder: NSCoder) {
diff --git a/ios/MullvadVPN/GeoJSON.swift b/ios/MullvadVPN/GeoJSON.swift
index cbc9c9f3b9..c33fab801b 100644
--- a/ios/MullvadVPN/GeoJSON.swift
+++ b/ios/MullvadVPN/GeoJSON.swift
@@ -6,8 +6,8 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import Foundation
import CoreLocation
+import Foundation
import MapKit
enum GeoJSON {}
@@ -32,15 +32,15 @@ extension GeoJSON {
}
var mkOverlays: [MKOverlay] {
- return features.flatMap { (feature) -> [MKOverlay] in
+ return features.flatMap { feature -> [MKOverlay] in
// Some tools like mapshaper output empty features after optimizing out the geometry
guard let geometry = feature.geometry else { return [] }
switch geometry {
- case .polygon(let polygon):
+ case let .polygon(polygon):
return polygon.mkPolygons
- case .multiPolygon(let multiPolygon):
+ case let .multiPolygon(multiPolygon):
return multiPolygon.mkPolygons
}
}
@@ -90,7 +90,11 @@ extension GeoJSON {
self = .multiPolygon(try decoder.singleValueContainer().decode(MultiPolygon.self))
default:
- throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "Geometry: Unknown type \(type)")
+ throw DecodingError.dataCorruptedError(
+ forKey: .type,
+ in: container,
+ debugDescription: "Geometry: Unknown type \(type)"
+ )
}
}
@@ -103,7 +107,7 @@ extension GeoJSON {
let coordinates: [[[Double]]]
var mkPolygons: [MKPolygon] {
- let coords = self.geoCoordinates
+ let coords = geoCoordinates
let exteriorCoordinates = coords.first ?? []
let exteriorPolygon = MKPolygon(
@@ -125,7 +129,10 @@ extension GeoJSON {
private var geoCoordinates: [[CLLocationCoordinate2D]] {
return coordinates.map { values -> [CLLocationCoordinate2D] in
return values.map { coordinates -> CLLocationCoordinate2D in
- return CLLocationCoordinate2D(latitude: coordinates[1], longitude: coordinates[0])
+ return CLLocationCoordinate2D(
+ latitude: coordinates[1],
+ longitude: coordinates[0]
+ )
}
}
}
diff --git a/ios/MullvadVPN/HeaderBarView.swift b/ios/MullvadVPN/HeaderBarView.swift
index e7527f2f18..714c9bdab8 100644
--- a/ios/MullvadVPN/HeaderBarView.swift
+++ b/ios/MullvadVPN/HeaderBarView.swift
@@ -82,17 +82,35 @@ class HeaderBarView: UIView {
logoImageView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
logoImageView.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor),
logoImageView.widthAnchor.constraint(equalToConstant: 44),
- logoImageView.heightAnchor.constraint(equalTo: logoImageView.widthAnchor, multiplier: 1),
+ logoImageView.heightAnchor.constraint(
+ equalTo: logoImageView.widthAnchor,
+ multiplier: 1
+ ),
- brandNameImageView.leadingAnchor.constraint(equalTo: logoImageView.trailingAnchor, constant: 9),
- brandNameImageView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 22),
- brandNameImageView.widthAnchor.constraint(equalTo: brandNameImageView.heightAnchor, multiplier: brandNameAspectRatio),
+ brandNameImageView.leadingAnchor.constraint(
+ equalTo: logoImageView.trailingAnchor,
+ constant: 9
+ ),
+ brandNameImageView.topAnchor.constraint(
+ equalTo: layoutMarginsGuide.topAnchor,
+ constant: 22
+ ),
+ brandNameImageView.widthAnchor.constraint(
+ equalTo: brandNameImageView.heightAnchor,
+ multiplier: brandNameAspectRatio
+ ),
brandNameImageView.heightAnchor.constraint(equalToConstant: 18),
- layoutMarginsGuide.bottomAnchor.constraint(equalTo: brandNameImageView.bottomAnchor, constant: 22),
+ layoutMarginsGuide.bottomAnchor.constraint(
+ equalTo: brandNameImageView.bottomAnchor,
+ constant: 22
+ ),
- settingsButton.leadingAnchor.constraint(greaterThanOrEqualTo: brandNameImageView.trailingAnchor, constant: 8),
+ settingsButton.leadingAnchor.constraint(
+ greaterThanOrEqualTo: brandNameImageView.trailingAnchor,
+ constant: 8
+ ),
settingsButton.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- settingsButton.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor)
+ settingsButton.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor),
]
[logoImageView, brandNameImageView, settingsButton].forEach { addSubview($0) }
diff --git a/ios/MullvadVPN/IPAddress+Codable.swift b/ios/MullvadVPN/IPAddress+Codable.swift
index d8802e85ca..2aafd53726 100644
--- a/ios/MullvadVPN/IPAddress+Codable.swift
+++ b/ios/MullvadVPN/IPAddress+Codable.swift
@@ -16,7 +16,10 @@ extension IPv4Address: Codable {
if let decoded = IPv4Address(ipString) {
self = decoded
} else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid IPv4 representation")
+ throw DecodingError.dataCorruptedError(
+ in: container,
+ debugDescription: "Invalid IPv4 representation"
+ )
}
}
@@ -35,7 +38,10 @@ extension IPv6Address: Codable {
if let decoded = IPv6Address(ipString) {
self = decoded
} else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid IPv6 representation")
+ throw DecodingError.dataCorruptedError(
+ in: container,
+ debugDescription: "Invalid IPv6 representation"
+ )
}
}
diff --git a/ios/MullvadVPN/IPEndpoint.swift b/ios/MullvadVPN/IPEndpoint.swift
index 31f2089a07..76d213192c 100644
--- a/ios/MullvadVPN/IPEndpoint.swift
+++ b/ios/MullvadVPN/IPEndpoint.swift
@@ -7,9 +7,9 @@
//
import Foundation
+import protocol Network.IPAddress
import struct Network.IPv4Address
import struct Network.IPv6Address
-import protocol Network.IPAddress
struct IPv4Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
let ip: IPv4Address
@@ -21,9 +21,15 @@ struct IPv4Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
}
init?<S>(string: S) where S: StringProtocol {
- let components = string.split(separator: ":", maxSplits: 2, omittingEmptySubsequences: false)
+ let components = string.split(
+ separator: ":",
+ maxSplits: 2,
+ omittingEmptySubsequences: false
+ )
- if components.count == 2, let parsedIP = IPv4Address(String(components[0])), let parsedPort = UInt16(components[1]) {
+ if components.count == 2, let parsedIP = IPv4Address(String(components[0])),
+ let parsedPort = UInt16(components[1])
+ {
ip = parsedIP
port = parsedPort
} else {
@@ -38,7 +44,10 @@ struct IPv4Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
if let parsedAddress = IPv4Endpoint(string: string) {
self = parsedAddress
} else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Cannot parse the IPv4 endpoint")
+ throw DecodingError.dataCorruptedError(
+ in: container,
+ debugDescription: "Cannot parse the IPv4 endpoint"
+ )
}
}
@@ -75,7 +84,7 @@ struct IPv6Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
let addressString = string[..<lastColon]
let portString = string[portIndex...]
- guard addressString.first == "[" && addressString.last == "]" else {
+ guard addressString.first == "[", addressString.last == "]" else {
return nil
}
@@ -96,7 +105,10 @@ struct IPv6Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
if let parsedAddress = IPv6Endpoint(string: string) {
self = parsedAddress
} else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Cannot parse the IPv6 endpoint")
+ throw DecodingError.dataCorruptedError(
+ in: container,
+ debugDescription: "Cannot parse the IPv6 endpoint"
+ )
}
}
@@ -121,18 +133,18 @@ enum AnyIPEndpoint: Hashable, Equatable, Codable, CustomStringConvertible {
var ip: IPAddress {
switch self {
- case .ipv4(let ipv4Endpoint):
+ case let .ipv4(ipv4Endpoint):
return ipv4Endpoint.ip
- case .ipv6(let ipv6Endpoint):
+ case let .ipv6(ipv6Endpoint):
return ipv6Endpoint.ip
}
}
var port: UInt16 {
switch self {
- case .ipv4(let ipv4Endpoint):
+ case let .ipv4(ipv4Endpoint):
return ipv4Endpoint.port
- case .ipv6(let ipv6Endpoint):
+ case let .ipv6(ipv6Endpoint):
return ipv6Endpoint.port
}
}
@@ -156,7 +168,10 @@ enum AnyIPEndpoint: Hashable, Equatable, Codable, CustomStringConvertible {
} else if let ipv6Endpoint = IPv6Endpoint(string: string) {
self = .ipv6(ipv6Endpoint)
} else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Cannot parse the endpoint")
+ throw DecodingError.dataCorruptedError(
+ in: container,
+ debugDescription: "Cannot parse the endpoint"
+ )
}
}
@@ -168,19 +183,19 @@ enum AnyIPEndpoint: Hashable, Equatable, Codable, CustomStringConvertible {
var description: String {
switch self {
- case .ipv4(let ipv4Endpoint):
+ case let .ipv4(ipv4Endpoint):
return "\(ipv4Endpoint)"
- case .ipv6(let ipv6Endpoint):
+ case let .ipv6(ipv6Endpoint):
return "\(ipv6Endpoint)"
}
}
static func == (lhs: AnyIPEndpoint, rhs: AnyIPEndpoint) -> Bool {
switch (lhs, rhs) {
- case (.ipv4(let lhsEndpoint), .ipv4(let rhsEndpoint)):
+ case let (.ipv4(lhsEndpoint), .ipv4(rhsEndpoint)):
return lhsEndpoint == rhsEndpoint
- case (.ipv6(let lhsEndpoint), .ipv6(let rhsEndpoint)):
+ case let (.ipv6(lhsEndpoint), .ipv6(rhsEndpoint)):
return lhsEndpoint == rhsEndpoint
default:
diff --git a/ios/MullvadVPN/InAppPurchaseButton.swift b/ios/MullvadVPN/InAppPurchaseButton.swift
index 483ccfdf4a..a87f277536 100644
--- a/ios/MullvadVPN/InAppPurchaseButton.swift
+++ b/ios/MullvadVPN/InAppPurchaseButton.swift
@@ -10,10 +10,9 @@ import Foundation
import UIKit
class InAppPurchaseButton: AppButton {
-
let activityIndicator = SpinnerActivityIndicatorView(style: .medium)
- var isLoading: Bool = false {
+ var isLoading = false {
didSet {
if isLoading {
activityIndicator.startAnimating()
@@ -51,7 +50,7 @@ class InAppPurchaseButton: AppButton {
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
var titleRect = super.titleRect(forContentRect: contentRect)
- let activityIndicatorRect = self.activityIndicatorRect(forContentRect: contentRect)
+ let activityIndicatorRect = activityIndicatorRect(forContentRect: contentRect)
// Adjust the title frame in case if it overlaps the activity indicator
let intersection = titleRect.intersection(activityIndicatorRect)
diff --git a/ios/MullvadVPN/IntentHandlers.swift b/ios/MullvadVPN/IntentHandlers.swift
index 8764df7ef9..36ad4b3bd6 100644
--- a/ios/MullvadVPN/IntentHandlers.swift
+++ b/ios/MullvadVPN/IntentHandlers.swift
@@ -12,7 +12,8 @@ final class StartVPNIntentHandler: NSObject, StartVPNIntentHandling {
func handle(intent: StartVPNIntent, completion: @escaping (StartVPNIntentResponse) -> Void) {
TunnelManager.shared.startTunnel { operationCompletion in
let code: StartVPNIntentResponseCode = operationCompletion.isSuccess
- ? .success : .failure
+ ? .success
+ : .failure
let response = StartVPNIntentResponse(code: code, userActivity: nil)
completion(response)
@@ -24,7 +25,8 @@ final class StopVPNIntentHandler: NSObject, StopVPNIntentHandling {
func handle(intent: StopVPNIntent, completion: @escaping (StopVPNIntentResponse) -> Void) {
TunnelManager.shared.stopTunnel { operationCompletion in
let code: StopVPNIntentResponseCode = operationCompletion.isSuccess
- ? .success : .failure
+ ? .success
+ : .failure
let response = StopVPNIntentResponse(code: code, userActivity: nil)
completion(response)
@@ -33,7 +35,10 @@ final class StopVPNIntentHandler: NSObject, StopVPNIntentHandling {
}
final class ReconnectVPNIntentHandler: NSObject, ReconnectVPNIntentHandling {
- func handle(intent: ReconnectVPNIntent, completion: @escaping (ReconnectVPNIntentResponse) -> Void) {
+ func handle(
+ intent: ReconnectVPNIntent,
+ completion: @escaping (ReconnectVPNIntentResponse) -> Void
+ ) {
let tunnelManager = TunnelManager.shared
tunnelManager.reconnectTunnel(selectNewRelay: true) { operationCompletion in
diff --git a/ios/MullvadVPN/LaunchViewController.swift b/ios/MullvadVPN/LaunchViewController.swift
index f108d8f6e4..02218244d5 100644
--- a/ios/MullvadVPN/LaunchViewController.swift
+++ b/ios/MullvadVPN/LaunchViewController.swift
@@ -9,7 +9,6 @@
import UIKit
class LaunchViewController: UIViewController {
-
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
@@ -28,7 +27,7 @@ class LaunchViewController: UIViewController {
initialController.didMove(toParent: self)
NSLayoutConstraint.activate([
- initialController.view.topAnchor.constraint(equalTo: view.topAnchor),
+ initialController.view.topAnchor.constraint(equalTo: view.topAnchor),
initialController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
initialController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
initialController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
diff --git a/ios/MullvadVPN/Location.swift b/ios/MullvadVPN/Location.swift
index 1d10f4c86e..ae8566a6e1 100644
--- a/ios/MullvadVPN/Location.swift
+++ b/ios/MullvadVPN/Location.swift
@@ -6,8 +6,8 @@
// Copyright © 2020 Mullvad VPN AB. All rights reserved.
//
-import Foundation
import struct CoreLocation.CLLocationCoordinate2D
+import Foundation
struct Location: Codable, Equatable {
var country: String
diff --git a/ios/MullvadVPN/LocationDataSource.swift b/ios/MullvadVPN/LocationDataSource.swift
index 6f7d922eb3..99f584e7b7 100644
--- a/ios/MullvadVPN/LocationDataSource.swift
+++ b/ios/MullvadVPN/LocationDataSource.swift
@@ -19,12 +19,12 @@ protocol LocationDataSourceItemProtocol {
}
class LocationDataSource: NSObject, UITableViewDataSource {
-
private var nodeByLocation = [RelayLocation: Node]()
private var locationList = [RelayLocation]()
private var rootNode = makeRootNode()
- typealias CellProviderBlock = (UITableView, IndexPath, LocationDataSourceItemProtocol) -> UITableViewCell?
+ typealias CellProviderBlock = (UITableView, IndexPath, LocationDataSourceItemProtocol)
+ -> UITableViewCell?
private let tableView: UITableView
private let cellProvider: CellProviderBlock
@@ -52,10 +52,16 @@ class LocationDataSource: NSObject, UITableViewDataSource {
tableView.dataSource = self
}
- func setSelectedRelayLocation(_ relayLocation: RelayLocation?, showHiddenParents: Bool, animated: Bool, scrollPosition: UITableView.ScrollPosition, completion: (() -> Void)? = nil) {
- self.selectedRelayLocation = relayLocation
- self.lastShowHiddenParents = showHiddenParents
- self.lastScrollPosition = scrollPosition
+ func setSelectedRelayLocation(
+ _ relayLocation: RelayLocation?,
+ showHiddenParents: Bool,
+ animated: Bool,
+ scrollPosition: UITableView.ScrollPosition,
+ completion: (() -> Void)? = nil
+ ) {
+ selectedRelayLocation = relayLocation
+ lastShowHiddenParents = showHiddenParents
+ lastScrollPosition = scrollPosition
if relayLocation == nil {
if let indexPath = tableView.indexPathForSelectedRow {
@@ -65,7 +71,11 @@ class LocationDataSource: NSObject, UITableViewDataSource {
} else {
let setSelection = {
if let indexPath = self.indexPathForSelectedRelay() {
- self.tableView.selectRow(at: indexPath, animated: animated, scrollPosition: scrollPosition)
+ self.tableView.selectRow(
+ at: indexPath,
+ animated: animated,
+ scrollPosition: scrollPosition
+ )
}
completion?()
}
@@ -78,15 +88,17 @@ class LocationDataSource: NSObject, UITableViewDataSource {
}
}
-
func setRelays(_ response: REST.ServerRelaysResponse) {
let rootNode = Self.makeRootNode()
var nodeByLocation = [RelayLocation: Node]()
let dataSourceWasEmpty = locationList.isEmpty
for relay in response.wireguard.relays {
- guard case .city(let countryCode, let cityCode) = RelayLocation(dashSeparatedString: relay.location),
- let serverLocation = response.locations[relay.location] else { continue }
+ guard case let .city(
+ countryCode,
+ cityCode
+ ) = RelayLocation(dashSeparatedString: relay.location),
+ let serverLocation = response.locations[relay.location] else { continue }
let relayLocation = RelayLocation.hostname(countryCode, cityCode, relay.hostname)
@@ -96,7 +108,8 @@ class LocationDataSource: NSObject, UITableViewDataSource {
}
// Maintain the `showsChildren` state when transitioning between relay lists
- let wasShowingChildren = self.nodeByLocation[ascendantOrSelf]?.showsChildren ?? false
+ let wasShowingChildren = self.nodeByLocation[ascendantOrSelf]?
+ .showsChildren ?? false
let node: Node
switch ascendantOrSelf {
@@ -111,7 +124,7 @@ class LocationDataSource: NSObject, UITableViewDataSource {
)
rootNode.addChild(node)
- case .city(let countryCode, _):
+ case let .city(countryCode, _):
node = Node(
type: .city,
location: ascendantOrSelf,
@@ -122,7 +135,7 @@ class LocationDataSource: NSObject, UITableViewDataSource {
)
nodeByLocation[.country(countryCode)]!.addChild(node)
- case .hostname(let countryCode, let cityCode, _):
+ case let .hostname(countryCode, cityCode, _):
node = Node(
type: .relay,
location: ascendantOrSelf,
@@ -142,33 +155,42 @@ class LocationDataSource: NSObject, UITableViewDataSource {
rootNode.computeActiveChildrenRecursive()
self.nodeByLocation = nodeByLocation
self.rootNode = rootNode
- self.locationList = rootNode.flatRelayLocationList()
+ locationList = rootNode.flatRelayLocationList()
tableView.reloadData()
let setSelection = { (_ scrollPosition: UITableView.ScrollPosition) in
if let indexPath = self.indexPathForSelectedRelay() {
- self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: scrollPosition)
+ self.tableView.selectRow(
+ at: indexPath,
+ animated: false,
+ scrollPosition: scrollPosition
+ )
}
}
// Sometimes the selected relay may be set before the data source is populated with relays.
// In that case restore the selection using cached parameters from the last call to
// `setSelectedRelayLocation`.
- if let selectedRelayLocation = self.selectedRelayLocation, dataSourceWasEmpty {
+ if let selectedRelayLocation = selectedRelayLocation, dataSourceWasEmpty {
if lastShowHiddenParents {
showParents(selectedRelayLocation, animated: false) {
setSelection(self.lastScrollPosition)
}
} else {
- setSelection(self.lastScrollPosition)
+ setSelection(lastScrollPosition)
}
} else {
setSelection(.none)
}
}
- func showChildren(_ relayLocation: RelayLocation, showHiddenParents: Bool = false, animated: Bool, completion: (() -> Void)? = nil) {
+ func showChildren(
+ _ relayLocation: RelayLocation,
+ showHiddenParents: Bool = false,
+ animated: Bool,
+ completion: (() -> Void)? = nil
+ ) {
toggleChildrenInternal(
relayLocation,
show: true,
@@ -178,7 +200,11 @@ class LocationDataSource: NSObject, UITableViewDataSource {
)
}
- func hideChildren(_ relayLocation: RelayLocation, animated: Bool, completion: (() -> Void)? = nil) {
+ func hideChildren(
+ _ relayLocation: RelayLocation,
+ animated: Bool,
+ completion: (() -> Void)? = nil
+ ) {
toggleChildrenInternal(
relayLocation,
show: false,
@@ -188,28 +214,60 @@ class LocationDataSource: NSObject, UITableViewDataSource {
)
}
- func toggleChildren(_ relayLocation: RelayLocation, animated: Bool, completion: (() -> Void)? = nil) {
- guard let node = self.nodeByLocation[relayLocation] else { return }
+ func toggleChildren(
+ _ relayLocation: RelayLocation,
+ animated: Bool,
+ completion: (() -> Void)? = nil
+ ) {
+ guard let node = nodeByLocation[relayLocation] else { return }
- toggleChildrenInternal(relayLocation, show: !node.showsChildren, showHiddenParents: false, animated: animated, completion: completion)
+ toggleChildrenInternal(
+ relayLocation,
+ show: !node.showsChildren,
+ showHiddenParents: false,
+ animated: animated,
+ completion: completion
+ )
}
- private func showParents(_ relayLocation: RelayLocation, animated: Bool, completion: (() -> Void)? = nil) {
+ private func showParents(
+ _ relayLocation: RelayLocation,
+ animated: Bool,
+ completion: (() -> Void)? = nil
+ ) {
switch relayLocation {
case .country:
completion?()
case .city:
if let countryLocation = relayLocation.ascendants.first {
- toggleChildrenInternal(countryLocation, show: true, showHiddenParents: false, animated: animated, completion: completion)
+ toggleChildrenInternal(
+ countryLocation,
+ show: true,
+ showHiddenParents: false,
+ animated: animated,
+ completion: completion
+ )
}
case .hostname:
if let cityLocation = relayLocation.ascendants.last {
- toggleChildrenInternal(cityLocation, show: true, showHiddenParents: true, animated: animated, completion: completion)
+ toggleChildrenInternal(
+ cityLocation,
+ show: true,
+ showHiddenParents: true,
+ animated: animated,
+ completion: completion
+ )
}
}
}
- private func toggleChildrenInternal(_ relayLocation: RelayLocation, show: Bool, showHiddenParents: Bool, animated: Bool, completion: (() -> Void)? = nil) {
+ private func toggleChildrenInternal(
+ _ relayLocation: RelayLocation,
+ show: Bool,
+ showHiddenParents: Bool,
+ animated: Bool,
+ completion: (() -> Void)? = nil
+ ) {
let affectedRelayLocations: [RelayLocation]
if showHiddenParents {
affectedRelayLocations = relayLocation.ascendants + [relayLocation]
@@ -217,21 +275,21 @@ class LocationDataSource: NSObject, UITableViewDataSource {
affectedRelayLocations = [relayLocation]
}
- let affectedNodes = affectedRelayLocations.compactMap { (relayLocation) -> Node? in
+ let affectedNodes = affectedRelayLocations.compactMap { relayLocation -> Node? in
return nodeByLocation[relayLocation]
}
// Pick the topmost node to expand or collapse
- guard let topNode = affectedNodes.first(where: { (node) -> Bool in
+ guard let topNode = affectedNodes.first(where: { node -> Bool in
return node.isCollapsible && node.showsChildren != show
}) else {
completion?()
return
}
- let numAffectedChildren = topNode.countChildrenRecursive { (node) -> Bool in
+ let numAffectedChildren = topNode.countChildrenRecursive { node -> Bool in
if show {
- return node.showsChildren || affectedNodes.contains(where: { (otherNode) -> Bool in
+ return node.showsChildren || affectedNodes.contains(where: { otherNode -> Bool in
return node === otherNode
})
} else {
@@ -242,17 +300,20 @@ class LocationDataSource: NSObject, UITableViewDataSource {
let applyChanges = { () -> ChangeSet? in
guard let topIndexPath = self.indexPath(for: topNode.location) else { return nil }
- affectedNodes.forEach { (node) in
+ affectedNodes.forEach { node in
node.showsChildren = show
}
let affectedRange = (topIndexPath.row + 1 ... topIndexPath.row + numAffectedChildren)
- let affectedIndexPaths = affectedRange.map { (row) -> IndexPath in
+ let affectedIndexPaths = affectedRange.map { row -> IndexPath in
return IndexPath(row: row, section: 0)
}
if show {
- self.locationList.insert(contentsOf: topNode.flatRelayLocationList(), at: topIndexPath.row + 1)
+ self.locationList.insert(
+ contentsOf: topNode.flatRelayLocationList(),
+ at: topIndexPath.row + 1
+ )
return ChangeSet(
insertIndexPaths: affectedIndexPaths,
@@ -283,7 +344,7 @@ class LocationDataSource: NSObject, UITableViewDataSource {
tableView.deleteRows(at: changeSet.deleteIndexPaths, with: .fade)
tableView.reloadRows(at: changeSet.updateIndexPaths, with: .none)
}
- } completion: { (finished) in
+ } completion: { finished in
restoreSelection()
completion?()
}
@@ -300,20 +361,20 @@ class LocationDataSource: NSObject, UITableViewDataSource {
}
func item(for indexPath: IndexPath) -> LocationDataSourceItemProtocol? {
- return self.relayLocation(for: indexPath)
- .flatMap { (relayLocation) -> Node? in
+ return relayLocation(for: indexPath)
+ .flatMap { relayLocation -> Node? in
return nodeByLocation[relayLocation]
}
}
func indexPath(for location: RelayLocation) -> IndexPath? {
- return locationList.firstIndex(of: location).map { (index) -> IndexPath in
+ return locationList.firstIndex(of: location).map { index -> IndexPath in
return IndexPath(row: index, section: 0)
}
}
func indexPathForSelectedRelay() -> IndexPath? {
- return selectedRelayLocation.flatMap { (relayLocation) -> IndexPath? in
+ return selectedRelayLocation.flatMap { relayLocation -> IndexPath? in
return self.indexPath(for: relayLocation)
}
}
@@ -331,13 +392,12 @@ class LocationDataSource: NSObject, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
assert(indexPath.section == 0)
- let item = self.item(for: indexPath)!
+ let item = item(for: indexPath)!
return cellProvider(tableView, indexPath, item)!
}
}
extension LocationDataSource {
-
private enum NodeType {
case root
case country
@@ -373,8 +433,15 @@ extension LocationDataSource {
}
}
- init(type: NodeType, location: RelayLocation, displayName: String, showsChildren: Bool, isActive: Bool, children: [Node]) {
- self.nodeType = type
+ init(
+ type: NodeType,
+ location: RelayLocation,
+ displayName: String,
+ showsChildren: Bool,
+ isActive: Bool,
+ children: [Node]
+ ) {
+ nodeType = type
self.location = location
self.displayName = displayName
self.showsChildren = showsChildren
@@ -388,7 +455,7 @@ extension LocationDataSource {
func sortChildrenRecursive() {
sortChildren()
- children.forEach { (node) in
+ children.forEach { node in
node.sortChildrenRecursive()
}
}
@@ -401,7 +468,7 @@ extension LocationDataSource {
}
fallthrough
case .city:
- isActive = children.contains(where: { (node) -> Bool in
+ isActive = children.contains(where: { node -> Bool in
return node.isActive
})
case .relay:
@@ -410,7 +477,7 @@ extension LocationDataSource {
}
func countChildrenRecursive(where condition: @escaping (Node) -> Bool) -> Int {
- return children.reduce(into: 0) { (numVisibleChildren, node) in
+ return children.reduce(into: 0) { numVisibleChildren, node in
numVisibleChildren += 1
if condition(node) {
numVisibleChildren += node.countChildrenRecursive(where: condition)
@@ -419,7 +486,7 @@ extension LocationDataSource {
}
func flatRelayLocationList() -> [RelayLocation] {
- return children.reduce(into: []) { (array, node) in
+ return children.reduce(into: []) { array, node in
Self.flatten(node: node, into: &array)
}
}
@@ -427,12 +494,15 @@ extension LocationDataSource {
private func sortChildren() {
switch nodeType {
case .root, .country:
- children.sort { (a, b) -> Bool in
+ children.sort { a, b -> Bool in
return lexicalSortComparator(a.displayName, b.displayName)
}
case .city:
- children.sort { (a, b) -> Bool in
- return fileSortComparator(a.location.stringRepresentation, b.location.stringRepresentation)
+ children.sort { a, b -> Bool in
+ return fileSortComparator(
+ a.location.stringRepresentation,
+ b.location.stringRepresentation
+ )
}
case .relay:
break
@@ -454,7 +524,6 @@ extension LocationDataSource {
let deleteIndexPaths: [IndexPath]
let updateIndexPaths: [IndexPath]
}
-
}
private func lexicalSortComparator(_ a: String, _ b: String) -> Bool {
diff --git a/ios/MullvadVPN/Logging/ChainedError+Logger.swift b/ios/MullvadVPN/Logging/ChainedError+Logger.swift
index 2d221c7132..0aede67701 100644
--- a/ios/MullvadVPN/Logging/ChainedError+Logger.swift
+++ b/ios/MullvadVPN/Logging/ChainedError+Logger.swift
@@ -18,8 +18,7 @@ extension Logger {
file: String = #file,
function: String = #function,
line: UInt = #line
- )
- {
+ ) {
log(
level: .error,
Message(
diff --git a/ios/MullvadVPN/Logging/CustomFormatLogHandler.swift b/ios/MullvadVPN/Logging/CustomFormatLogHandler.swift
index 340f83d8ae..37b326a2d4 100644
--- a/ios/MullvadVPN/Logging/CustomFormatLogHandler.swift
+++ b/ios/MullvadVPN/Logging/CustomFormatLogHandler.swift
@@ -38,21 +38,23 @@ struct CustomFormatLogHandler: LogHandler {
}
}
- func log(level: Logger.Level,
- message: Logger.Message,
- metadata: Logger.Metadata?,
- source: String,
- file: String,
- function: String,
- line: UInt)
- {
- let mergedMetadata = self.metadata.merging(metadata ?? [:]) { (lhs, rhs) -> Logger.MetadataValue in
- return rhs
- }
+ func log(
+ level: Logger.Level,
+ message: Logger.Message,
+ metadata: Logger.Metadata?,
+ source: String,
+ file: String,
+ function: String,
+ line: UInt
+ ) {
+ let mergedMetadata = self.metadata
+ .merging(metadata ?? [:]) { lhs, rhs -> Logger.MetadataValue in
+ return rhs
+ }
let prettyMetadata = Self.formatMetadata(mergedMetadata)
- let metadataOutput = prettyMetadata.isEmpty ? "" : " \(prettyMetadata)"
+ let metadataOutput = prettyMetadata.isEmpty ? "" : " \(prettyMetadata)"
let timestamp = dateFormatter.string(from: Date())
- let formattedMessage = "[\(timestamp)][\(self.label)][\(level)]\(metadataOutput) \(message)\n"
+ let formattedMessage = "[\(timestamp)][\(label)][\(level)]\(metadataOutput) \(message)\n"
for var stream in streams {
stream.write(formattedMessage)
diff --git a/ios/MullvadVPN/Logging/LogRotation.swift b/ios/MullvadVPN/Logging/LogRotation.swift
index 16d48b84df..ff7671ae80 100644
--- a/ios/MullvadVPN/Logging/LogRotation.swift
+++ b/ios/MullvadVPN/Logging/LogRotation.swift
@@ -9,7 +9,6 @@
import Foundation
enum LogRotation {
-
enum Error: ChainedError {
case noSourceLogFile
case moveSourceLogFile(Swift.Error)
@@ -49,7 +48,8 @@ enum LogRotation {
// .fileNoSuchFile is returned when both backup and source log files do not exist
// .fileReadNoSuchFile is returned when backup exists but source log file does not
if fileError.code == .fileNoSuchFile || fileError.code == .fileReadNoSuchFile,
- fileError.url == source {
+ fileError.url == source
+ {
throw Error.noSourceLogFile
}
}
diff --git a/ios/MullvadVPN/Logging/Logging.swift b/ios/MullvadVPN/Logging/Logging.swift
index 55451b677b..8d4f4f883f 100644
--- a/ios/MullvadVPN/Logging/Logging.swift
+++ b/ios/MullvadVPN/Logging/Logging.swift
@@ -10,21 +10,29 @@ import Foundation
import Logging
func initLoggingSystem(bundleIdentifier: String, metadata: Logger.Metadata? = nil) {
- let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier)!
+ let containerURL = FileManager.default
+ .containerURL(
+ forSecurityApplicationGroupIdentifier: ApplicationConfiguration
+ .securityGroupIdentifier
+ )!
let logsDirectoryURL = containerURL.appendingPathComponent("Logs", isDirectory: true)
let logFileName = "\(bundleIdentifier).log"
let logFileURL = logsDirectoryURL.appendingPathComponent(logFileName)
// Create Logs folder within container if it doesn't exist
- try? FileManager.default.createDirectory(at: logsDirectoryURL, withIntermediateDirectories: false, attributes: nil)
+ try? FileManager.default.createDirectory(
+ at: logsDirectoryURL,
+ withIntermediateDirectories: false,
+ attributes: nil
+ )
// Rotate log
var logRotationError: Error?
do {
try LogRotation.rotateLog(
- logsDirectory: logsDirectoryURL,
- logFileName: logFileName
- )
+ logsDirectory: logsDirectoryURL,
+ logFileName: logFileName
+ )
} catch {
logRotationError = error
}
@@ -38,11 +46,11 @@ func initLoggingSystem(bundleIdentifier: String, metadata: Logger.Metadata? = ni
}
// Configure Logging system
- LoggingSystem.bootstrap { (label) -> LogHandler in
+ LoggingSystem.bootstrap { label -> LogHandler in
var logHandlers: [LogHandler] = []
#if DEBUG
- logHandlers.append(OSLogHandler(subsystem: bundleIdentifier, category: label))
+ logHandlers.append(OSLogHandler(subsystem: bundleIdentifier, category: label))
#endif
if !streams.isEmpty {
diff --git a/ios/MullvadVPN/Logging/OSLogHandler.swift b/ios/MullvadVPN/Logging/OSLogHandler.swift
index 8fcddcea15..0b71bd08e5 100644
--- a/ios/MullvadVPN/Logging/OSLogHandler.swift
+++ b/ios/MullvadVPN/Logging/OSLogHandler.swift
@@ -40,8 +40,8 @@ struct OSLogHandler: LogHandler {
}
init(subsystem: String, category: String) {
- self.label = category
- self.osLog = OSLogHandler.getOSLog(subsystem: subsystem, category: category)
+ label = category
+ osLog = OSLogHandler.getOSLog(subsystem: subsystem, category: category)
}
subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? {
@@ -53,17 +53,19 @@ struct OSLogHandler: LogHandler {
}
}
- func log(level: Logging.Logger.Level,
- message: Logging.Logger.Message,
- metadata: Logging.Logger.Metadata?,
- source: String,
- file: String,
- function: String,
- line: UInt)
- {
- let mergedMetadata = self.metadata.merging(metadata ?? [:]) { (lhs, rhs) -> Logging.Logger.MetadataValue in
- return rhs
- }
+ func log(
+ level: Logging.Logger.Level,
+ message: Logging.Logger.Message,
+ metadata: Logging.Logger.Metadata?,
+ source: String,
+ file: String,
+ function: String,
+ line: UInt
+ ) {
+ let mergedMetadata = self.metadata
+ .merging(metadata ?? [:]) { lhs, rhs -> Logging.Logger.MetadataValue in
+ return rhs
+ }
let prettyMetadata = Self.formatMetadata(mergedMetadata)
let logMessage = prettyMetadata.isEmpty ? message : "\(prettyMetadata) \(message)"
@@ -74,6 +76,7 @@ struct OSLogHandler: LogHandler {
return metadata.map { "\($0)=\($1)" }.joined(separator: " ")
}
}
+
extension Logging.Logger.Level {
var osLogType: OSLogType {
switch self {
diff --git a/ios/MullvadVPN/Logging/TextFileOutputStream.swift b/ios/MullvadVPN/Logging/TextFileOutputStream.swift
index 751f897b7d..95387b53ec 100644
--- a/ios/MullvadVPN/Logging/TextFileOutputStream.swift
+++ b/ios/MullvadVPN/Logging/TextFileOutputStream.swift
@@ -14,19 +14,27 @@ class TextFileOutputStream: TextOutputStream {
private let queue = DispatchQueue.global(qos: .utility)
class func standardOutputStream(encoding: String.Encoding = .utf8) -> TextFileOutputStream {
- return TextFileOutputStream(fileDescriptor: FileHandle.standardOutput.fileDescriptor, encoding: encoding)
+ return TextFileOutputStream(
+ fileDescriptor: FileHandle.standardOutput.fileDescriptor,
+ encoding: encoding
+ )
}
init(fileDescriptor: Int32, encoding: String.Encoding = .utf8) {
self.encoding = encoding
- writer = DispatchIO(type: .stream, fileDescriptor: fileDescriptor, queue: queue) { (errno) in
+ writer = DispatchIO(type: .stream, fileDescriptor: fileDescriptor, queue: queue) { errno in
if errno != 0 {
print("TextFileOutputStream: closed channel with error: \(errno)")
}
}
}
- init?(fileURL: URL, createFile: Bool, filePermissions: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, encoding: String.Encoding = .utf8) {
+ init?(
+ fileURL: URL,
+ createFile: Bool,
+ filePermissions: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
+ encoding: String.Encoding = .utf8
+ ) {
var oflag: Int32 = O_WRONLY
var mode: mode_t = .zero
if createFile {
@@ -34,13 +42,20 @@ class TextFileOutputStream: TextOutputStream {
mode = filePermissions
}
- let queue = self.queue
- let writer = fileURL.path.withCString { (filePathPointer) -> DispatchIO? in
- return DispatchIO(type: .stream, path: filePathPointer, oflag: oflag, mode: mode, queue: queue, cleanupHandler: { (errno) in
- if errno != 0 {
- print("TextFileOutputStream: closed channel with error: \(errno)")
+ let queue = queue
+ let writer = fileURL.path.withCString { filePathPointer -> DispatchIO? in
+ return DispatchIO(
+ type: .stream,
+ path: filePathPointer,
+ oflag: oflag,
+ mode: mode,
+ queue: queue,
+ cleanupHandler: { errno in
+ if errno != 0 {
+ print("TextFileOutputStream: closed channel with error: \(errno)")
+ }
}
- })
+ )
}
if let writer = writer {
@@ -56,12 +71,17 @@ class TextFileOutputStream: TextOutputStream {
}
func write(_ string: String) {
- string.data(using: encoding)?.withUnsafeBytes { (bytes) in
- writer.write(offset: .zero, data: DispatchData(bytes: bytes), queue: queue) { (done, data, errno) in
- if errno != 0 {
- print("TextFileOutputStream: write error: \(errno)")
+ string.data(using: encoding)?.withUnsafeBytes { bytes in
+ writer
+ .write(
+ offset: .zero,
+ data: DispatchData(bytes: bytes),
+ queue: queue
+ ) { done, data, errno in
+ if errno != 0 {
+ print("TextFileOutputStream: write error: \(errno)")
+ }
}
- }
}
}
}
diff --git a/ios/MullvadVPN/LoginContentView.swift b/ios/MullvadVPN/LoginContentView.swift
index 661ab8401e..a89d6c80ef 100644
--- a/ios/MullvadVPN/LoginContentView.swift
+++ b/ios/MullvadVPN/LoginContentView.swift
@@ -9,7 +9,6 @@
import UIKit
class LoginContentView: UIView {
-
private var keyboardResponder: AutomaticKeyboardResponder?
let titleLabel: UILabel = {
@@ -114,12 +113,15 @@ class LoginContentView: UIView {
accountInputGroup.textField.accessibilityIdentifier = "LoginTextField"
- keyboardResponder = AutomaticKeyboardResponder(targetView: self, handler: { [weak self] (view, adjustment) in
- self?.contentContainerBottomConstraint?.constant = adjustment
+ keyboardResponder = AutomaticKeyboardResponder(
+ targetView: self,
+ handler: { [weak self] view, adjustment in
+ self?.contentContainerBottomConstraint?.constant = adjustment
- self?.layoutIfNeeded()
- self?.updateStatusImageVisibility(animated: false)
- })
+ self?.layoutIfNeeded()
+ self?.updateStatusImageVisibility(animated: false)
+ }
+ )
addSubviews()
}
@@ -139,7 +141,8 @@ class LoginContentView: UIView {
private func updateStatusImageVisibility(animated: Bool) {
let statusImageFrame = statusImageView.convert(statusImageView.bounds, to: self)
- let shouldShow = isStatusImageVisible && safeAreaLayoutGuide.layoutFrame.contains(statusImageFrame)
+ let shouldShow = isStatusImageVisible && safeAreaLayoutGuide.layoutFrame
+ .contains(statusImageFrame)
let actions = {
// Only display the status image if it doesn't overlap the safe area layout guide.
@@ -175,7 +178,8 @@ class LoginContentView: UIView {
addSubview(contentContainer)
addSubview(footerContainer)
- let contentContainerBottomConstraint = bottomAnchor.constraint(equalTo: contentContainer.bottomAnchor)
+ let contentContainerBottomConstraint = bottomAnchor
+ .constraint(equalTo: contentContainer.bottomAnchor)
self.contentContainerBottomConstraint = contentContainerBottomConstraint
NSLayoutConstraint.activate([
@@ -189,17 +193,28 @@ class LoginContentView: UIView {
footerContainer.bottomAnchor.constraint(equalTo: bottomAnchor),
footerLabel.topAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.topAnchor),
- footerLabel.leadingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
- footerLabel.trailingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
+ footerLabel.leadingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
+ footerLabel.trailingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
- createAccountButton.topAnchor.constraint(equalToSystemSpacingBelow: footerLabel.bottomAnchor, multiplier: 1),
- createAccountButton.leadingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
- createAccountButton.trailingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
- createAccountButton.bottomAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.bottomAnchor),
+ createAccountButton.topAnchor.constraint(
+ equalToSystemSpacingBelow: footerLabel.bottomAnchor,
+ multiplier: 1
+ ),
+ createAccountButton.leadingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
+ createAccountButton.trailingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
+ createAccountButton.bottomAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.bottomAnchor),
statusImageView.centerXAnchor.constraint(equalTo: contentContainer.centerXAnchor),
formContainer.topAnchor.constraint(equalTo: statusImageView.bottomAnchor, constant: 30),
- formContainer.centerYAnchor.constraint(equalTo: contentContainer.centerYAnchor, constant: -20),
+ formContainer.centerYAnchor.constraint(
+ equalTo: contentContainer.centerYAnchor,
+ constant: -20
+ ),
formContainer.leadingAnchor.constraint(equalTo: contentContainer.leadingAnchor),
formContainer.trailingAnchor.constraint(equalTo: contentContainer.trailingAnchor),
formContainer.bottomAnchor.constraint(equalTo: accountInputGroupWrapper.bottomAnchor),
@@ -208,22 +223,36 @@ class LoginContentView: UIView {
activityIndicator.centerYAnchor.constraint(equalTo: statusImageView.centerYAnchor),
titleLabel.topAnchor.constraint(equalTo: formContainer.topAnchor),
- titleLabel.leadingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
- titleLabel.trailingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
+ titleLabel.leadingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
+ titleLabel.trailingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
- messageLabel.topAnchor.constraint(equalToSystemSpacingBelow: titleLabel.bottomAnchor, multiplier: 1),
- messageLabel.leadingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
- messageLabel.trailingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
+ messageLabel.topAnchor.constraint(
+ equalToSystemSpacingBelow: titleLabel.bottomAnchor,
+ multiplier: 1
+ ),
+ messageLabel.leadingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
+ messageLabel.trailingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
- accountInputGroupWrapper.topAnchor.constraint(equalToSystemSpacingBelow: messageLabel.bottomAnchor, multiplier: 1),
- accountInputGroupWrapper.leadingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
- accountInputGroupWrapper.trailingAnchor.constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
- accountInputGroupWrapper.heightAnchor.constraint(equalTo: accountInputGroup.contentView.heightAnchor),
+ accountInputGroupWrapper.topAnchor.constraint(
+ equalToSystemSpacingBelow: messageLabel.bottomAnchor,
+ multiplier: 1
+ ),
+ accountInputGroupWrapper.leadingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.leadingAnchor),
+ accountInputGroupWrapper.trailingAnchor
+ .constraint(equalTo: formContainer.layoutMarginsGuide.trailingAnchor),
+ accountInputGroupWrapper.heightAnchor
+ .constraint(equalTo: accountInputGroup.contentView.heightAnchor),
accountInputGroup.topAnchor.constraint(equalTo: accountInputGroupWrapper.topAnchor),
- accountInputGroup.leadingAnchor.constraint(equalTo: accountInputGroupWrapper.leadingAnchor),
- accountInputGroup.trailingAnchor.constraint(equalTo: accountInputGroupWrapper.trailingAnchor),
+ accountInputGroup.leadingAnchor
+ .constraint(equalTo: accountInputGroupWrapper.leadingAnchor),
+ accountInputGroup.trailingAnchor
+ .constraint(equalTo: accountInputGroupWrapper.trailingAnchor),
])
}
-
}
diff --git a/ios/MullvadVPN/LoginViewController.swift b/ios/MullvadVPN/LoginViewController.swift
index b6e9a3df71..20890e4ecf 100644
--- a/ios/MullvadVPN/LoginViewController.swift
+++ b/ios/MullvadVPN/LoginViewController.swift
@@ -6,8 +6,8 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
enum LoginAction {
case useExistingAccount(String)
@@ -15,7 +15,7 @@ enum LoginAction {
var setAccountAction: SetAccountAction {
switch self {
- case .useExistingAccount(let accountNumber):
+ case let .useExistingAccount(accountNumber):
return .existing(accountNumber)
case .createAccount:
return .new
@@ -41,16 +41,17 @@ protocol LoginViewControllerDelegate: AnyObject {
}
class LoginViewController: UIViewController, RootContainment {
-
private lazy var contentView: LoginContentView = {
let view = LoginContentView(frame: self.view.bounds)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
- private lazy var accountInputAccessoryCancelButton: UIBarButtonItem = {
- return UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelLogin))
- }()
+ private lazy var accountInputAccessoryCancelButton = UIBarButtonItem(
+ barButtonSystemItem: .cancel,
+ target: self,
+ action: #selector(cancelLogin)
+ )
private lazy var accountInputAccessoryLoginButton: UIBarButtonItem = {
let barButtonItem = UIBarButtonItem(
@@ -74,7 +75,7 @@ class LoginViewController: UIViewController, RootContainment {
toolbar.items = [
self.accountInputAccessoryCancelButton,
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
- self.accountInputAccessoryLoginButton
+ self.accountInputAccessoryLoginButton,
]
toolbar.sizeToFit()
return toolbar
@@ -129,7 +130,8 @@ class LoginViewController: UIViewController, RootContainment {
// There is no need to set the input accessory toolbar on iPad since it has a dedicated
// button to dismiss the keyboard.
if case .phone = UIDevice.current.userInterfaceIdiom {
- contentView.accountInputGroup.textField.inputAccessoryView = self.accountInputAccessoryToolbar
+ contentView.accountInputGroup.textField.inputAccessoryView = self
+ .accountInputAccessoryToolbar
} else {
contentView.accountInputGroup.textField.inputAccessoryView = nil
}
@@ -140,12 +142,18 @@ class LoginViewController: UIViewController, RootContainment {
let notificationCenter = NotificationCenter.default
- contentView.createAccountButton.addTarget(self, action: #selector(createNewAccount), for: .touchUpInside)
+ contentView.createAccountButton.addTarget(
+ self,
+ action: #selector(createNewAccount),
+ for: .touchUpInside
+ )
- notificationCenter.addObserver(self,
- selector: #selector(textDidChange(_:)),
- name: UITextField.textDidChangeNotification,
- object: contentView.accountInputGroup.textField)
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(textDidChange(_:)),
+ name: UITextField.textDidChangeNotification,
+ object: contentView.accountInputGroup.textField
+ )
}
override var disablesAutomaticKeyboardDismissal: Bool {
@@ -164,20 +172,21 @@ class LoginViewController: UIViewController, RootContainment {
func start(action: LoginAction) {
beginLogin(action)
- delegate?.loginViewController(self, shouldHandleLoginAction: action) { [weak self] completion in
- switch completion {
- case .success(let accountData):
- if case .createAccount = action {
- self?.contentView.accountInputGroup.setAccount(accountData?.number ?? "")
- }
+ delegate?
+ .loginViewController(self, shouldHandleLoginAction: action) { [weak self] completion in
+ switch completion {
+ case let .success(accountData):
+ if case .createAccount = action {
+ self?.contentView.accountInputGroup.setAccount(accountData?.number ?? "")
+ }
- self?.endLogin(.success(action))
- case .failure(let error):
- self?.endLogin(.failure(error))
- case .cancelled:
- self?.endLogin(.default)
+ self?.endLogin(.success(action))
+ case let .failure(error):
+ self?.endLogin(.failure(error))
+ case .cancelled:
+ self?.endLogin(.default)
+ }
}
- }
}
func reset() {
@@ -226,8 +235,10 @@ class LoginViewController: UIViewController, RootContainment {
contentView.accountInputGroup.setLastUsedAccount(accountNumber, animated: false)
} catch {
- logger.error(chainedError: AnyChainedError(error),
- message: "Failed to update last used account.")
+ logger.error(
+ chainedError: AnyChainedError(error),
+ message: "Failed to update last used account."
+ )
}
}
@@ -298,7 +309,7 @@ class LoginViewController: UIViewController, RootContainment {
// Disable "Create account" button on iPad as user types in the account token,
// however leave it enabled on iPhone to avoid confusion to why it's being disabled
// since it's likely overlayed by keyboard.
- if case .pad = self.traitCollection.userInterfaceIdiom {
+ if case .pad = traitCollection.userInterfaceIdiom {
isEnabled = contentView.accountInputGroup.textField.text?.isEmpty ?? true
} else {
isEnabled = true
@@ -369,7 +380,7 @@ private extension LoginState {
comment: ""
)
- case .authenticating(let method):
+ case let .authenticating(method):
switch method {
case .useExistingAccount:
return NSLocalizedString(
@@ -387,10 +398,10 @@ private extension LoginState {
)
}
- case .failure(let error):
+ case let .failure(error):
return error.localizedDescription
- case .success(let method):
+ case let .success(method):
switch method {
case .useExistingAccount:
return NSLocalizedString(
@@ -419,8 +430,10 @@ extension LoginViewController: AccountInputGroupViewDelegate {
try SettingsManager.setLastUsedAccount(nil)
return true
} catch {
- logger.error(chainedError: AnyChainedError(error),
- message: "Failed to remove last used account.")
+ logger.error(
+ chainedError: AnyChainedError(error),
+ message: "Failed to remove last used account."
+ )
return false
}
}
diff --git a/ios/MullvadVPN/NEProviderStopReason+Debug.swift b/ios/MullvadVPN/NEProviderStopReason+Debug.swift
index eab9028dbe..35d5339c58 100644
--- a/ios/MullvadVPN/NEProviderStopReason+Debug.swift
+++ b/ios/MullvadVPN/NEProviderStopReason+Debug.swift
@@ -13,42 +13,41 @@ extension NEProviderStopReason: CustomStringConvertible {
public var description: String {
switch self {
case .none:
- return "none"
+ return "none"
case .userInitiated:
- return "user initiated"
+ return "user initiated"
case .providerFailed:
- return "provider failed"
+ return "provider failed"
case .noNetworkAvailable:
- return "no network available"
+ return "no network available"
case .unrecoverableNetworkChange:
- return "unrecoverable network change"
+ return "unrecoverable network change"
case .providerDisabled:
- return "provider disabled"
+ return "provider disabled"
case .authenticationCanceled:
- return "authentication cancelled"
+ return "authentication cancelled"
case .configurationFailed:
- return "configuration failed"
+ return "configuration failed"
case .idleTimeout:
- return "idle timeout"
+ return "idle timeout"
case .configurationDisabled:
- return "configuration disabled"
+ return "configuration disabled"
case .configurationRemoved:
- return "configuration removed"
+ return "configuration removed"
case .superceded:
- return "superceded"
+ return "superceded"
case .userLogout:
- return "user logout"
+ return "user logout"
case .userSwitch:
- return "user switch"
+ return "user switch"
case .connectionFailed:
- return "connection failed"
+ return "connection failed"
case .sleep:
- return "sleep"
+ return "sleep"
case .appUpdate:
- return "app update"
+ return "app update"
@unknown default:
- return "unknown value (\(self.rawValue))"
+ return "unknown value (\(rawValue))"
}
}
}
-
diff --git a/ios/MullvadVPN/NEVPNStatus+Debug.swift b/ios/MullvadVPN/NEVPNStatus+Debug.swift
index ba612d8b1a..37520fb3d5 100644
--- a/ios/MullvadVPN/NEVPNStatus+Debug.swift
+++ b/ios/MullvadVPN/NEVPNStatus+Debug.swift
@@ -21,11 +21,11 @@ extension NEVPNStatus: CustomStringConvertible {
case .disconnecting:
return "disconnecting"
case .invalid:
- return "invalid"
+ return "invalid"
case .reasserting:
return "reasserting"
@unknown default:
- return "unknown value (\(self.rawValue))"
+ return "unknown value (\(rawValue))"
}
}
}
diff --git a/ios/MullvadVPN/NSAttributedString+Markdown.swift b/ios/MullvadVPN/NSAttributedString+Markdown.swift
index af13fb5b95..5e7c064b9d 100644
--- a/ios/MullvadVPN/NSAttributedString+Markdown.swift
+++ b/ios/MullvadVPN/NSAttributedString+Markdown.swift
@@ -13,7 +13,8 @@ extension NSAttributedString {
let attributedString = NSMutableAttributedString()
let components = markdownString.components(separatedBy: "**")
- let fontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold) ?? font.fontDescriptor
+ let fontDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold) ?? font
+ .fontDescriptor
let boldFont = UIFont(descriptor: fontDescriptor, size: font.pointSize)
for (index, string) in components.enumerated() {
diff --git a/ios/MullvadVPN/NotificationBannerView.swift b/ios/MullvadVPN/NotificationBannerView.swift
index 5c46fabd74..bd74ee3dbf 100644
--- a/ios/MullvadVPN/NotificationBannerView.swift
+++ b/ios/MullvadVPN/NotificationBannerView.swift
@@ -24,7 +24,6 @@ enum NotificationBannerStyle {
}
class NotificationBannerView: UIView {
-
private static let indicatorViewSize = CGSize(width: 12, height: 12)
private let backgroundView: UIVisualEffectView = {
@@ -116,22 +115,31 @@ class NotificationBannerView: UIView {
wrapperView.topAnchor.constraint(equalTo: backgroundView.contentView.topAnchor),
wrapperView.leadingAnchor.constraint(equalTo: backgroundView.contentView.leadingAnchor),
- wrapperView.trailingAnchor.constraint(equalTo: backgroundView.contentView.trailingAnchor),
+ wrapperView.trailingAnchor
+ .constraint(equalTo: backgroundView.contentView.trailingAnchor),
wrapperView.bottomAnchor.constraint(equalTo: backgroundView.contentView.bottomAnchor),
indicatorView.bottomAnchor.constraint(equalTo: titleLabel.firstBaselineAnchor),
- indicatorView.leadingAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.leadingAnchor),
+ indicatorView.leadingAnchor
+ .constraint(equalTo: wrapperView.layoutMarginsGuide.leadingAnchor),
indicatorView.widthAnchor.constraint(equalToConstant: Self.indicatorViewSize.width),
indicatorView.heightAnchor.constraint(equalToConstant: Self.indicatorViewSize.height),
titleLabel.topAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.topAnchor),
- titleLabel.leadingAnchor.constraint(equalToSystemSpacingAfter: indicatorView.trailingAnchor, multiplier: 1),
- titleLabel.trailingAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.trailingAnchor),
+ titleLabel.leadingAnchor.constraint(
+ equalToSystemSpacingAfter: indicatorView.trailingAnchor,
+ multiplier: 1
+ ),
+ titleLabel.trailingAnchor
+ .constraint(equalTo: wrapperView.layoutMarginsGuide.trailingAnchor),
- bodyLabel.topAnchor.constraint(equalToSystemSpacingBelow: titleLabel.bottomAnchor, multiplier: 1),
+ bodyLabel.topAnchor.constraint(
+ equalToSystemSpacingBelow: titleLabel.bottomAnchor,
+ multiplier: 1
+ ),
bodyLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
bodyLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
- bodyLabel.bottomAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.bottomAnchor)
+ bodyLabel.bottomAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.bottomAnchor),
])
}
diff --git a/ios/MullvadVPN/NotificationController.swift b/ios/MullvadVPN/NotificationController.swift
index ed7d03e0ee..9585c26ff9 100644
--- a/ios/MullvadVPN/NotificationController.swift
+++ b/ios/MullvadVPN/NotificationController.swift
@@ -85,7 +85,10 @@ class NotificationController: UIViewController {
}
if animated {
- let timing = UISpringTimingParameters(dampingRatio: 0.7, initialVelocity: CGVector(dx: 0, dy: 1))
+ let timing = UISpringTimingParameters(
+ dampingRatio: 0.7,
+ initialVelocity: CGVector(dx: 0, dy: 1)
+ )
let animator = UIViewPropertyAnimator(duration: 0.8, timingParameters: timing)
animator.isInterruptible = false
animator.addAnimations {
@@ -112,7 +115,10 @@ class NotificationController: UIViewController {
bannerView.accessibilityLabel = "\(notification.title)\n\(notification.body)"
if animated {
- let animator = UIViewPropertyAnimator(duration: 0.25, timingParameters: UICubicTimingParameters(animationCurve: .easeOut))
+ let animator = UIViewPropertyAnimator(
+ duration: 0.25,
+ timingParameters: UICubicTimingParameters(animationCurve: .easeOut)
+ )
animator.addAnimations {
self.view.layoutIfNeeded()
}
@@ -138,7 +144,9 @@ class NotificationController: UIViewController {
private func updateAccessibilityFrame() {
let layoutFrame = bannerView.layoutMarginsGuide.layoutFrame
- bannerView.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(layoutFrame, in: view)
+ bannerView.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(
+ layoutFrame,
+ in: view
+ )
}
-
}
diff --git a/ios/MullvadVPN/NotificationManager.swift b/ios/MullvadVPN/NotificationManager.swift
index d2b1842cd6..63468e70a3 100644
--- a/ios/MullvadVPN/NotificationManager.swift
+++ b/ios/MullvadVPN/NotificationManager.swift
@@ -7,15 +7,18 @@
//
import Foundation
-import UserNotifications
import Logging
import UIKit
+import UserNotifications
protocol NotificationManagerDelegate: AnyObject {
- func notificationManagerDidUpdateInAppNotifications(_ manager: NotificationManager, notifications: [InAppNotificationDescriptor])
+ func notificationManagerDidUpdateInAppNotifications(
+ _ manager: NotificationManager,
+ notifications: [InAppNotificationDescriptor]
+ )
}
-fileprivate protocol NotificationProviderDelegate: AnyObject {
+private protocol NotificationProviderDelegate: AnyObject {
func notificationProviderDidInvalidate(_ notificationProvider: NotificationProvider)
}
@@ -27,8 +30,9 @@ class NotificationProvider {
}
func invalidate() {
- let executor = { () -> Void in
+ let executor = {
self.delegate?.notificationProviderDidInvalidate(self)
+ return
}
if Thread.isMainThread {
@@ -62,7 +66,6 @@ protocol InAppNotificationProvider {
}
class NotificationManager: NotificationProviderDelegate {
-
private lazy var logger = Logger(label: "NotificationManager")
var notificationProviders: [NotificationProvider] = [] {
@@ -87,7 +90,10 @@ class NotificationManager: NotificationProviderDelegate {
didSet {
// Pump in-app notifications when changing delegate.
if !inAppNotificationDescriptors.isEmpty {
- delegate?.notificationManagerDidUpdateInAppNotifications(self, notifications: inAppNotificationDescriptors)
+ delegate?.notificationManagerDidUpdateInAppNotifications(
+ self,
+ notifications: inAppNotificationDescriptors
+ )
}
}
}
@@ -127,14 +133,16 @@ class NotificationManager: NotificationProviderDelegate {
}
let notificationCenter = UNUserNotificationCenter.current()
- notificationCenter.removePendingNotificationRequests(withIdentifiers: pendingRequestIdentifiersToRemove)
- notificationCenter.removeDeliveredNotifications(withIdentifiers: deliveredRequestIdentifiersToRemove)
+ notificationCenter
+ .removePendingNotificationRequests(withIdentifiers: pendingRequestIdentifiersToRemove)
+ notificationCenter
+ .removeDeliveredNotifications(withIdentifiers: deliveredRequestIdentifiersToRemove)
- requestNotificationPermissions { (granted) in
+ requestNotificationPermissions { granted in
guard granted else { return }
for newRequest in newSystemNotificationRequests {
- notificationCenter.add(newRequest) { (error) in
+ notificationCenter.add(newRequest) { error in
if let error = error {
self.logger.error(
chainedError: AnyChainedError(error),
@@ -147,7 +155,10 @@ class NotificationManager: NotificationProviderDelegate {
inAppNotificationDescriptors = newInAppNotificationDescriptors
- delegate?.notificationManagerDidUpdateInAppNotifications(self, notifications: newInAppNotificationDescriptors)
+ delegate?.notificationManagerDidUpdateInAppNotifications(
+ self,
+ notifications: newInAppNotificationDescriptors
+ )
}
// MARK: - Private
@@ -156,18 +167,19 @@ class NotificationManager: NotificationProviderDelegate {
let authorizationOptions: UNAuthorizationOptions = [.alert, .sound, .provisional]
let userNotificationCenter = UNUserNotificationCenter.current()
- userNotificationCenter.getNotificationSettings { (notificationSettings) in
+ userNotificationCenter.getNotificationSettings { notificationSettings in
switch notificationSettings.authorizationStatus {
case .notDetermined:
- userNotificationCenter.requestAuthorization(options: authorizationOptions) { (granted, error) in
- if let error = error {
- self.logger.error(
- chainedError: AnyChainedError(error),
- message: "Failed to obtain user notifications authorization"
- )
+ userNotificationCenter
+ .requestAuthorization(options: authorizationOptions) { granted, error in
+ if let error = error {
+ self.logger.error(
+ chainedError: AnyChainedError(error),
+ message: "Failed to obtain user notifications authorization"
+ )
+ }
+ completion(granted)
}
- completion(granted)
- }
case .authorized, .provisional:
completion(true)
@@ -191,20 +203,31 @@ class NotificationManager: NotificationProviderDelegate {
let notificationCenter = UNUserNotificationCenter.current()
if notificationProvider.shouldRemovePendingRequests {
- notificationCenter.removePendingNotificationRequests(withIdentifiers: [notificationProvider.identifier])
+ notificationCenter
+ .removePendingNotificationRequests(withIdentifiers: [
+ notificationProvider
+ .identifier,
+ ])
}
if notificationProvider.shouldRemoveDeliveredRequests {
- notificationCenter.removeDeliveredNotifications(withIdentifiers: [notificationProvider.identifier])
+ notificationCenter
+ .removeDeliveredNotifications(withIdentifiers: [
+ notificationProvider
+ .identifier,
+ ])
}
if let request = notificationProvider.notificationRequest {
- requestNotificationPermissions { (granted) in
+ requestNotificationPermissions { granted in
guard granted else { return }
- notificationCenter.add(request) { (error) in
+ notificationCenter.add(request) { error in
if let error = error {
- self.logger.error("Failed to add notification request with identifier \(request.identifier). Error: \(error.localizedDescription)")
+ self.logger
+ .error(
+ "Failed to add notification request with identifier \(request.identifier). Error: \(error.localizedDescription)"
+ )
}
}
}
@@ -216,24 +239,30 @@ class NotificationManager: NotificationProviderDelegate {
var newNotificationDescriptors = inAppNotificationDescriptors
if let replaceNotificationDescriptor = notificationProvider.notificationDescriptor {
- newNotificationDescriptors = notificationProviders.compactMap { (notificationProvider) -> InAppNotificationDescriptor? in
- if replaceNotificationDescriptor.identifier == notificationProvider.identifier {
- return replaceNotificationDescriptor
- } else {
- return inAppNotificationDescriptors.first { (descriptor) in
- return descriptor.identifier == notificationProvider.identifier
+ newNotificationDescriptors = notificationProviders
+ .compactMap { notificationProvider -> InAppNotificationDescriptor? in
+ if replaceNotificationDescriptor.identifier == notificationProvider
+ .identifier
+ {
+ return replaceNotificationDescriptor
+ } else {
+ return inAppNotificationDescriptors.first { descriptor in
+ return descriptor.identifier == notificationProvider.identifier
+ }
}
}
- }
} else {
- newNotificationDescriptors.removeAll { (descriptor) in
+ newNotificationDescriptors.removeAll { descriptor in
return descriptor.identifier == notificationProvider.identifier
}
}
inAppNotificationDescriptors = newNotificationDescriptors
- delegate?.notificationManagerDidUpdateInAppNotifications(self, notifications: inAppNotificationDescriptors)
+ delegate?.notificationManagerDidUpdateInAppNotifications(
+ self,
+ notifications: inAppNotificationDescriptors
+ )
}
}
}
diff --git a/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift b/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
index ae3942ca30..1ace9cc5bb 100644
--- a/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
@@ -12,7 +12,9 @@ import UserNotifications
let accountExpiryNotificationIdentifier = "net.mullvad.MullvadVPN.AccountExpiryNotification"
let accountExpiryDefaultTriggerInterval = 3
-class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificationProvider, InAppNotificationProvider, TunnelObserver {
+class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificationProvider,
+ InAppNotificationProvider, TunnelObserver
+{
private var accountExpiry: Date?
/// Interval prior to expiry used to calculate when to trigger notifications.
@@ -35,13 +37,20 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
guard let accountExpiry = accountExpiry else { return nil }
// Subtract 3 days from expiry date
- guard let triggerDate = Calendar.current.date(byAdding: .day, value: -triggerInterval, to: accountExpiry) else { return nil }
+ guard let triggerDate = Calendar.current.date(
+ byAdding: .day,
+ value: -triggerInterval,
+ to: accountExpiry
+ ) else { return nil }
// Do not produce notification if less than 3 days left till expiry
guard triggerDate > Date() else { return nil }
// Create date components for calendar trigger
- let dateComponents = Calendar.current.dateComponents([.second, .minute, .hour, .day, .month, .year], from: triggerDate)
+ let dateComponents = Calendar.current.dateComponents(
+ [.second, .minute, .hour, .day, .month, .year],
+ from: triggerDate
+ )
return UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
}
@@ -65,8 +74,14 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
)
let content = UNMutableNotificationContent()
- content.title = NSString.localizedUserNotificationString(forKey: "ACCOUNT_EXPIRY_SYSTEM_NOTIFICATION_TITLE", arguments: nil)
- content.body = NSString.localizedUserNotificationString(forKey: "ACCOUNT_EXPIRY_SYSTEM_NOTIFICATION_BODY", arguments: nil)
+ content.title = NSString.localizedUserNotificationString(
+ forKey: "ACCOUNT_EXPIRY_SYSTEM_NOTIFICATION_TITLE",
+ arguments: nil
+ )
+ content.body = NSString.localizedUserNotificationString(
+ forKey: "ACCOUNT_EXPIRY_SYSTEM_NOTIFICATION_BODY",
+ arguments: nil
+ )
content.sound = UNNotificationSound.default
return UNNotificationRequest(
@@ -92,11 +107,15 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
guard let accountExpiry = accountExpiry else { return nil }
// Subtract 3 days from expiry date
- guard let triggerDate = Calendar.current.date(byAdding: .day, value: -triggerInterval, to: accountExpiry) else { return nil }
+ guard let triggerDate = Calendar.current.date(
+ byAdding: .day,
+ value: -triggerInterval,
+ to: accountExpiry
+ ) else { return nil }
// Only produce in-app notification within the last 3 days till expiry
let now = Date()
- guard triggerDate < now && now < accountExpiry else { return nil }
+ guard triggerDate < now, now < accountExpiry else { return nil }
// Format the remaining duration
let formatter = DateComponentsFormatter()
@@ -107,7 +126,7 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
guard let duration = formatter.string(from: now, to: accountExpiry) else { return nil }
return InAppNotificationDescriptor(
- identifier: self.identifier,
+ identifier: identifier,
style: .warning,
title: NSLocalizedString(
"ACCOUNT_EXPIRY_INAPP_NOTIFICATION_TITLE",
@@ -143,12 +162,14 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
func tunnelManager(_ manager: TunnelManager, didUpdateDeviceState deviceState: DeviceState) {
invalidate(deviceState: manager.deviceState)
}
-
}
diff --git a/ios/MullvadVPN/Notifications/TunnelErrorNotificationProvider.swift b/ios/MullvadVPN/Notifications/TunnelErrorNotificationProvider.swift
index 24c21479f2..6c50218e22 100644
--- a/ios/MullvadVPN/Notifications/TunnelErrorNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/TunnelErrorNotificationProvider.swift
@@ -8,7 +8,9 @@
import Foundation
-class TunnelErrorNotificationProvider: NotificationProvider, InAppNotificationProvider, TunnelObserver {
+class TunnelErrorNotificationProvider: NotificationProvider, InAppNotificationProvider,
+ TunnelObserver
+{
override var identifier: String {
return "net.mullvad.MullvadVPN.TunnelErrorNotificationProvider"
}
@@ -55,7 +57,10 @@ class TunnelErrorNotificationProvider: NotificationProvider, InAppNotificationPr
invalidate()
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
diff --git a/ios/MullvadVPN/ObserverList.swift b/ios/MullvadVPN/ObserverList.swift
index b936ae3bdf..a2093c9809 100644
--- a/ios/MullvadVPN/ObserverList.swift
+++ b/ios/MullvadVPN/ObserverList.swift
@@ -13,7 +13,7 @@ struct WeakBox<T> {
return valueProvider()
}
- private let valueProvider: (() -> T?)
+ private let valueProvider: () -> T?
init(_ value: T) {
let reference = value as AnyObject
diff --git a/ios/MullvadVPN/Operations/AsyncBlockOperation.swift b/ios/MullvadVPN/Operations/AsyncBlockOperation.swift
index 9c4101fdff..03872873f9 100644
--- a/ios/MullvadVPN/Operations/AsyncBlockOperation.swift
+++ b/ios/MullvadVPN/Operations/AsyncBlockOperation.swift
@@ -79,4 +79,3 @@ class AsyncBlockOperation: AsyncOperation {
}
}
}
-
diff --git a/ios/MullvadVPN/Operations/AsyncOperation.swift b/ios/MullvadVPN/Operations/AsyncOperation.swift
index 1655098af6..b384fd2bee 100644
--- a/ios/MullvadVPN/Operations/AsyncOperation.swift
+++ b/ios/MullvadVPN/Operations/AsyncOperation.swift
@@ -60,7 +60,7 @@ class AsyncOperation: Operation {
/// Backing variable for `_isCancelled`.
/// Access must be guarded with `stateLock`.
- private var __isCancelled: Bool = false
+ private var __isCancelled = false
/// Backing variable for `error`.
/// Access must be guarded with `stateLock`.
@@ -113,7 +113,7 @@ class AsyncOperation: Operation {
}
}
- final override var isReady: Bool {
+ override final var isReady: Bool {
stateLock.lock()
defer { stateLock.unlock() }
@@ -136,19 +136,19 @@ class AsyncOperation: Operation {
}
}
- final override var isExecuting: Bool {
+ override final var isExecuting: Bool {
return state == .executing
}
- final override var isFinished: Bool {
+ override final var isFinished: Bool {
return state == .finished
}
- final override var isCancelled: Bool {
+ override final var isCancelled: Bool {
return _isCancelled
}
- final override var isAsynchronous: Bool {
+ override final var isAsynchronous: Bool {
return true
}
@@ -237,7 +237,12 @@ class AsyncOperation: Operation {
self.dispatchQueue = dispatchQueue ?? DispatchQueue(label: "AsyncOperation.dispatchQueue")
super.init()
- addObserver(self, forKeyPath: #keyPath(isReady), options: [], context: &Self.observerContext)
+ addObserver(
+ self,
+ forKeyPath: #keyPath(isReady),
+ options: [],
+ context: &Self.observerContext
+ )
}
deinit {
@@ -251,10 +256,9 @@ class AsyncOperation: Operation {
override func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
- change: [NSKeyValueChangeKey : Any]?,
+ change: [NSKeyValueChangeKey: Any]?,
context: UnsafeMutableRawPointer?
- )
- {
+ ) {
if context == &Self.observerContext {
checkReadiness()
return
@@ -282,7 +286,7 @@ class AsyncOperation: Operation {
// MARK: - Lifecycle
- final override func start() {
+ override final func start() {
let currentQueue = OperationQueue.current
let underlyingQueue = currentQueue?.underlyingQueue
@@ -316,7 +320,7 @@ class AsyncOperation: Operation {
// Override in subclasses
}
- final override func cancel() {
+ override final func cancel() {
var notifyDidCancel = false
operationLock.lock()
@@ -415,7 +419,6 @@ extension Operation {
}
}
-
protocol OperationBlockObserverSupport {}
extension AsyncOperation: OperationBlockObserverSupport {}
diff --git a/ios/MullvadVPN/Operations/AsyncOperationQueue.swift b/ios/MullvadVPN/Operations/AsyncOperationQueue.swift
index 2476f2abd6..86a9cb0891 100644
--- a/ios/MullvadVPN/Operations/AsyncOperationQueue.swift
+++ b/ios/MullvadVPN/Operations/AsyncOperationQueue.swift
@@ -95,5 +95,4 @@ private final class ExclusivityManager {
}
}
}
-
}
diff --git a/ios/MullvadVPN/Operations/BackgroundObserver.swift b/ios/MullvadVPN/Operations/BackgroundObserver.swift
index 6e8e0562c7..b946d03440 100644
--- a/ios/MullvadVPN/Operations/BackgroundObserver.swift
+++ b/ios/MullvadVPN/Operations/BackgroundObserver.swift
@@ -7,48 +7,47 @@
#if canImport(UIKit)
-import UIKit
+ import UIKit
-class BackgroundObserver: OperationObserver {
- let name: String
- let application: UIApplication
- let cancelUponExpiration: Bool
+ class BackgroundObserver: OperationObserver {
+ let name: String
+ let application: UIApplication
+ let cancelUponExpiration: Bool
- private var taskIdentifier: UIBackgroundTaskIdentifier?
+ private var taskIdentifier: UIBackgroundTaskIdentifier?
- init(
- application: UIApplication = .shared,
- name: String,
- cancelUponExpiration: Bool
- )
- {
- self.application = application
- self.name = name
- self.cancelUponExpiration = cancelUponExpiration
- }
+ init(
+ application: UIApplication = .shared,
+ name: String,
+ cancelUponExpiration: Bool
+ ) {
+ self.application = application
+ self.name = name
+ self.cancelUponExpiration = cancelUponExpiration
+ }
- func didAttach(to operation: Operation) {
- let expirationHandler = cancelUponExpiration ? { operation.cancel() } : nil
+ func didAttach(to operation: Operation) {
+ let expirationHandler = cancelUponExpiration ? { operation.cancel() } : nil
- taskIdentifier = application.beginBackgroundTask(
- withName: name,
- expirationHandler: expirationHandler
- )
- }
+ taskIdentifier = application.beginBackgroundTask(
+ withName: name,
+ expirationHandler: expirationHandler
+ )
+ }
- func operationDidStart(_ operation: Operation) {
- // no-op
- }
+ func operationDidStart(_ operation: Operation) {
+ // no-op
+ }
- func operationDidCancel(_ operation: Operation) {
- // no-op
- }
+ func operationDidCancel(_ operation: Operation) {
+ // no-op
+ }
- func operationDidFinish(_ operation: Operation, error: Error?) {
- if let taskIdentifier = taskIdentifier {
- application.endBackgroundTask(taskIdentifier)
+ func operationDidFinish(_ operation: Operation, error: Error?) {
+ if let taskIdentifier = taskIdentifier {
+ application.endBackgroundTask(taskIdentifier)
+ }
}
}
-}
#endif
diff --git a/ios/MullvadVPN/Operations/InputInjectionBuilder.swift b/ios/MullvadVPN/Operations/InputInjectionBuilder.swift
index 87fff94146..ba4c0ea968 100644
--- a/ios/MullvadVPN/Operations/InputInjectionBuilder.swift
+++ b/ios/MullvadVPN/Operations/InputInjectionBuilder.swift
@@ -84,7 +84,7 @@ class InputInjectionBuilder<OperationType, Context> where OperationType: InputOp
extension InputInjectionBuilder
where Context: OperationInputContext,
- Context.Input == OperationType.Input
+ Context.Input == OperationType.Input
{
func reduce() {
reduce { context in
diff --git a/ios/MullvadVPN/Operations/OperationCompletion.swift b/ios/MullvadVPN/Operations/OperationCompletion.swift
index 5bb73071a3..c4a9f90a88 100644
--- a/ios/MullvadVPN/Operations/OperationCompletion.swift
+++ b/ios/MullvadVPN/Operations/OperationCompletion.swift
@@ -22,7 +22,7 @@ enum OperationCompletion<Success, Failure: Error> {
}
var value: Success? {
- if case .success(let value) = self {
+ if case let .success(value) = self {
return value
} else {
return nil
@@ -30,7 +30,7 @@ enum OperationCompletion<Success, Failure: Error> {
}
var error: Failure? {
- if case .failure(let error) = self {
+ if case let .failure(error) = self {
return error
} else {
return nil
@@ -39,9 +39,9 @@ enum OperationCompletion<Success, Failure: Error> {
var result: Result<Success, Failure>? {
switch self {
- case .success(let value):
+ case let .success(value):
return .success(value)
- case .failure(let error):
+ case let .failure(error):
return .failure(error)
case .cancelled:
return nil
@@ -50,9 +50,9 @@ enum OperationCompletion<Success, Failure: Error> {
init(result: Result<Success, Failure>) {
switch result {
- case .success(let value):
+ case let .success(value):
self = .success(value)
- case .failure(let error):
+ case let .failure(error):
self = .failure(error)
}
}
@@ -65,59 +65,70 @@ enum OperationCompletion<Success, Failure: Error> {
}
}
- func map<NewSuccess>(_ block: (Success) -> NewSuccess) -> OperationCompletion<NewSuccess, Failure> {
+ func map<NewSuccess>(_ block: (Success) -> NewSuccess)
+ -> OperationCompletion<NewSuccess, Failure>
+ {
switch self {
- case .success(let value):
+ case let .success(value):
return .success(block(value))
- case .failure(let error):
+ case let .failure(error):
return .failure(error)
case .cancelled:
return .cancelled
}
}
- func mapError<NewFailure: Error>(_ block: (Failure) -> NewFailure) -> OperationCompletion<Success, NewFailure> {
+ func mapError<NewFailure: Error>(_ block: (Failure) -> NewFailure)
+ -> OperationCompletion<Success, NewFailure>
+ {
switch self {
- case .success(let value):
+ case let .success(value):
return .success(value)
- case .failure(let error):
+ case let .failure(error):
return .failure(block(error))
case .cancelled:
return .cancelled
}
}
- func flatMap<NewSuccess>(_ block: (Success) -> OperationCompletion<NewSuccess, Failure>) -> OperationCompletion<NewSuccess, Failure> {
+ func flatMap<NewSuccess>(_ block: (Success) -> OperationCompletion<NewSuccess, Failure>)
+ -> OperationCompletion<NewSuccess, Failure>
+ {
switch self {
- case .success(let value):
+ case let .success(value):
return block(value)
- case .failure(let error):
+ case let .failure(error):
return .failure(error)
case .cancelled:
return .cancelled
}
}
- func flatMapError<NewFailure: Error>(_ block: (Failure) -> OperationCompletion<Success, NewFailure>) -> OperationCompletion<Success, NewFailure> {
+ func flatMapError<NewFailure: Error>(
+ _ block: (Failure)
+ -> OperationCompletion<Success, NewFailure>
+ ) -> OperationCompletion<Success, NewFailure> {
switch self {
- case .success(let value):
+ case let .success(value):
return .success(value)
- case .failure(let error):
+ case let .failure(error):
return block(error)
case .cancelled:
return .cancelled
}
}
- func tryMap<NewSuccess>(_ block: (Success) throws -> NewSuccess) -> OperationCompletion<NewSuccess, Error> {
+ func tryMap<NewSuccess>(_ block: (Success) throws -> NewSuccess)
+ -> OperationCompletion<NewSuccess, Error>
+ {
switch self {
- case .success(let value):
+ case let .success(value):
do {
return .success(try block(value))
} catch {
return .failure(error)
}
- case .failure(let error):
+ case let .failure(error):
return .failure(error)
case .cancelled:
return .cancelled
diff --git a/ios/MullvadVPN/Operations/OperationCondition.swift b/ios/MullvadVPN/Operations/OperationCondition.swift
index 64d4f385fa..024ca52013 100644
--- a/ios/MullvadVPN/Operations/OperationCondition.swift
+++ b/ios/MullvadVPN/Operations/OperationCondition.swift
@@ -53,7 +53,7 @@ final class NoFailedDependenciesCondition: OperationCondition {
return false
}
- if operation.isCancelled && !self.ignoreCancellations {
+ if operation.isCancelled, !self.ignoreCancellations {
return false
}
diff --git a/ios/MullvadVPN/Operations/OperationObserver.swift b/ios/MullvadVPN/Operations/OperationObserver.swift
index 0cb42e54f1..fd9fb61bfa 100644
--- a/ios/MullvadVPN/Operations/OperationObserver.swift
+++ b/ios/MullvadVPN/Operations/OperationObserver.swift
@@ -30,8 +30,7 @@ class OperationBlockObserver<OperationType: Operation>: OperationObserver {
didStart: VoidBlock? = nil,
didCancel: VoidBlock? = nil,
didFinish: FinishBlock? = nil
- )
- {
+ ) {
_didAttach = didAttach
_didStart = didStart
_didCancel = didCancel
diff --git a/ios/MullvadVPN/Operations/PresentAlertOperation.swift b/ios/MullvadVPN/Operations/PresentAlertOperation.swift
index 3c4227b4bd..3a3976de7a 100644
--- a/ios/MullvadVPN/Operations/PresentAlertOperation.swift
+++ b/ios/MullvadVPN/Operations/PresentAlertOperation.swift
@@ -13,7 +13,11 @@ class PresentAlertOperation: AsyncOperation {
private let presentingController: UIViewController
private let presentCompletion: (() -> Void)?
- init(alertController: UIAlertController, presentingController: UIViewController, presentCompletion: (() -> Void)? = nil) {
+ init(
+ alertController: UIAlertController,
+ presentingController: UIViewController,
+ presentCompletion: (() -> Void)? = nil
+ ) {
self.alertController = alertController
self.presentingController = presentingController
self.presentCompletion = presentCompletion
@@ -26,7 +30,7 @@ class PresentAlertOperation: AsyncOperation {
guard isExecuting else { return }
// Guard against dismissing controller during transition.
- if !alertController.isBeingPresented && !alertController.isBeingDismissed {
+ if !alertController.isBeingPresented, !alertController.isBeingDismissed {
dismissAndFinish()
}
}
@@ -34,12 +38,12 @@ class PresentAlertOperation: AsyncOperation {
override func main() {
NotificationCenter.default.addObserver(
self,
- selector: #selector(self.alertControllerDidDismiss(_:)),
+ selector: #selector(alertControllerDidDismiss(_:)),
name: AlertPresenter.alertControllerDidDismissNotification,
- object: self.alertController
+ object: alertController
)
- presentingController.present(self.alertController, animated: true) {
+ presentingController.present(alertController, animated: true) {
self.presentCompletion?()
// Alert operation was cancelled during transition?
@@ -53,7 +57,7 @@ class PresentAlertOperation: AsyncOperation {
NotificationCenter.default.removeObserver(
self,
name: AlertPresenter.alertControllerDidDismissNotification,
- object: self.alertController
+ object: alertController
)
alertController.dismiss(animated: false) {
diff --git a/ios/MullvadVPN/Operations/ProductsRequestOperation.swift b/ios/MullvadVPN/Operations/ProductsRequestOperation.swift
index 877b52c08c..cc80b9e3f4 100644
--- a/ios/MullvadVPN/Operations/ProductsRequestOperation.swift
+++ b/ios/MullvadVPN/Operations/ProductsRequestOperation.swift
@@ -9,7 +9,9 @@
import Foundation
import StoreKit
-class ProductsRequestOperation: ResultOperation<SKProductsResponse, Error>, SKProductsRequestDelegate {
+class ProductsRequestOperation: ResultOperation<SKProductsResponse, Error>,
+ SKProductsRequestDelegate
+{
private let productIdentifiers: Set<String>
private let maxRetryCount = 10
@@ -78,7 +80,7 @@ class ProductsRequestOperation: ResultOperation<SKProductsResponse, Error>, SKPr
self?.finish(completion: .failure(error))
}
- retryTimer?.schedule(wallDeadline: .now() + self.retryDelay)
+ retryTimer?.schedule(wallDeadline: .now() + retryDelay)
retryTimer?.activate()
}
}
diff --git a/ios/MullvadVPN/Operations/ResultBlockOperation.swift b/ios/MullvadVPN/Operations/ResultBlockOperation.swift
index c59c623002..c9616d958d 100644
--- a/ios/MullvadVPN/Operations/ResultBlockOperation.swift
+++ b/ios/MullvadVPN/Operations/ResultBlockOperation.swift
@@ -18,8 +18,7 @@ class ResultBlockOperation<Success, Failure: Error>: ResultOperation<Success, Fa
convenience init(
dispatchQueue: DispatchQueue? = nil,
executionBlock: ExecutionBlock? = nil
- )
- {
+ ) {
self.init(
dispatchQueue: dispatchQueue,
executionBlock: executionBlock,
@@ -31,8 +30,7 @@ class ResultBlockOperation<Success, Failure: Error>: ResultOperation<Success, Fa
convenience init(
dispatchQueue: DispatchQueue? = nil,
executionBlock: @escaping ThrowingExecutionBlock
- )
- {
+ ) {
self.init(
dispatchQueue: dispatchQueue,
executionBlock: Self.wrapThrowingBlock(executionBlock),
@@ -46,8 +44,7 @@ class ResultBlockOperation<Success, Failure: Error>: ResultOperation<Success, Fa
executionBlock: ExecutionBlock?,
completionQueue: DispatchQueue?,
completionHandler: CompletionHandler?
- )
- {
+ ) {
self.executionBlock = executionBlock
super.init(
@@ -99,7 +96,9 @@ class ResultBlockOperation<Success, Failure: Error>: ResultOperation<Success, Fa
}
}
- private class func wrapThrowingBlock(_ executionBlock: @escaping ThrowingExecutionBlock) -> ExecutionBlock {
+ private class func wrapThrowingBlock(_ executionBlock: @escaping ThrowingExecutionBlock)
+ -> ExecutionBlock
+ {
return { operation in
do {
let value = try executionBlock()
@@ -113,4 +112,3 @@ class ResultBlockOperation<Success, Failure: Error>: ResultOperation<Success, Fa
}
}
}
-
diff --git a/ios/MullvadVPN/Operations/ResultOperation.swift b/ios/MullvadVPN/Operations/ResultOperation.swift
index dbbb050d4c..4d7ec4b7ce 100644
--- a/ios/MullvadVPN/Operations/ResultOperation.swift
+++ b/ios/MullvadVPN/Operations/ResultOperation.swift
@@ -63,8 +63,7 @@ class ResultOperation<Success, Failure: Error>: AsyncOperation {
dispatchQueue: DispatchQueue?,
completionQueue: DispatchQueue?,
completionHandler: CompletionHandler?
- )
- {
+ ) {
_completionQueue = completionQueue
_completionHandler = completionHandler
diff --git a/ios/MullvadVPN/Operations/TransformOperation.swift b/ios/MullvadVPN/Operations/TransformOperation.swift
index 2a2f5e2b5a..abca23077a 100644
--- a/ios/MullvadVPN/Operations/TransformOperation.swift
+++ b/ios/MullvadVPN/Operations/TransformOperation.swift
@@ -41,8 +41,7 @@ final class TransformOperation<Input, Output, Failure: Error>:
dispatchQueue: DispatchQueue? = nil,
input: Input? = nil,
block: ExecutionBlock? = nil
- )
- {
+ ) {
_input = input
executionBlock = block
@@ -53,8 +52,7 @@ final class TransformOperation<Input, Output, Failure: Error>:
dispatchQueue: DispatchQueue? = nil,
input: Input? = nil,
throwingBlock: @escaping ThrowingExecutionBlock
- )
- {
+ ) {
_input = input
executionBlock = Self.wrapThrowingBlock(throwingBlock)
@@ -119,7 +117,9 @@ final class TransformOperation<Input, Output, Failure: Error>:
}
}
- private class func wrapThrowingBlock(_ executionBlock: @escaping ThrowingExecutionBlock) -> ExecutionBlock {
+ private class func wrapThrowingBlock(_ executionBlock: @escaping ThrowingExecutionBlock)
+ -> ExecutionBlock
+ {
return { input, operation in
do {
let value = try executionBlock(input)
@@ -133,4 +133,3 @@ final class TransformOperation<Input, Output, Failure: Error>:
}
}
}
-
diff --git a/ios/MullvadVPN/PreferencesDataSource.swift b/ios/MullvadVPN/PreferencesDataSource.swift
index 46c0dc5470..6451571bf4 100644
--- a/ios/MullvadVPN/PreferencesDataSource.swift
+++ b/ios/MullvadVPN/PreferencesDataSource.swift
@@ -105,7 +105,8 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
// Reconfigure cells for items with corresponding DNS entries that were changed during sanitization.
let itemsToReload: [Item] = oldDNSDomains.filter { oldDNSEntry in
- guard let newDNSEntry = viewModel.dnsEntry(entryIdentifier: oldDNSEntry.identifier) else { return false }
+ guard let newDNSEntry = viewModel.dnsEntry(entryIdentifier: oldDNSEntry.identifier)
+ else { return false }
return newDNSEntry.address != oldDNSEntry.address
}.map { dnsEntry in
@@ -124,7 +125,7 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
tableView?.reloadData()
}
- if !editing && viewModelBeforeEditing != viewModel {
+ if !editing, viewModelBeforeEditing != viewModel {
delegate?.preferencesDataSource(self, didChangeViewModel: viewModel)
}
}
@@ -172,14 +173,18 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
}
- func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
+ func tableView(
+ _ tableView: UITableView,
+ commit editingStyle: UITableViewCell.EditingStyle,
+ forRowAt indexPath: IndexPath
+ ) {
let item = snapshot.itemForIndexPath(indexPath)
if case .addDNSServer = item, editingStyle == .insert {
addDNSServerEntry()
}
- if case .dnsServer(let entryIdentifier) = item, editingStyle == .delete {
+ if case let .dnsServer(entryIdentifier) = item, editingStyle == .delete {
deleteDNSServerEntry(entryIdentifier: entryIdentifier)
}
}
@@ -195,14 +200,19 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
}
- func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
+ func tableView(
+ _ tableView: UITableView,
+ moveRowAt sourceIndexPath: IndexPath,
+ to destinationIndexPath: IndexPath
+ ) {
let sourceItem = snapshot.itemForIndexPath(sourceIndexPath)!
let destinationItem = snapshot.itemForIndexPath(destinationIndexPath)!
- guard case .dnsServer(let sourceIdentifier) = sourceItem,
- case .dnsServer(let targetIdentifier) = destinationItem,
+ guard case let .dnsServer(sourceIdentifier) = sourceItem,
+ case let .dnsServer(targetIdentifier) = destinationItem,
let sourceIndex = viewModel.indexOfDNSEntry(entryIdentifier: sourceIdentifier),
- let destinationIndex = viewModel.indexOfDNSEntry(entryIdentifier: targetIdentifier) else { return }
+ let destinationIndex = viewModel.indexOfDNSEntry(entryIdentifier: targetIdentifier)
+ else { return }
let removedEntry = viewModel.customDNSDomains.remove(at: sourceIndex)
viewModel.customDNSDomains.insert(removedEntry, at: destinationIndex)
@@ -217,7 +227,11 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
- return tableView.dequeueReusableHeaderFooterView(withIdentifier: HeaderFooterReuseIdentifiers.spacer.rawValue)
+ return tableView
+ .dequeueReusableHeaderFooterView(
+ withIdentifier: HeaderFooterReuseIdentifiers.spacer
+ .rawValue
+ )
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
@@ -228,7 +242,11 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return nil
case .customDNS:
- let reusableView = tableView.dequeueReusableHeaderFooterView(withIdentifier: HeaderFooterReuseIdentifiers.customDNSFooter.rawValue) as! SettingsStaticTextFooterView
+ let reusableView = tableView
+ .dequeueReusableHeaderFooterView(
+ withIdentifier: HeaderFooterReuseIdentifiers
+ .customDNSFooter.rawValue
+ ) as! SettingsStaticTextFooterView
configureFooterView(reusableView)
return reusableView
}
@@ -255,7 +273,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
}
- func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
+ func tableView(
+ _ tableView: UITableView,
+ editingStyleForRowAt indexPath: IndexPath
+ ) -> UITableViewCell.EditingStyle {
let item = snapshot.itemForIndexPath(indexPath)
switch item {
@@ -268,7 +289,11 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
}
- func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
+ func tableView(
+ _ tableView: UITableView,
+ targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath,
+ toProposedIndexPath proposedDestinationIndexPath: IndexPath
+ ) -> IndexPath {
guard let sectionIdentifier = snapshot.section(at: sourceIndexPath.section),
case .customDNS = sectionIdentifier else { return sourceIndexPath }
@@ -300,18 +325,27 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
private func registerClasses() {
CellReuseIdentifiers.allCases.forEach { enumCase in
- tableView?.register(enumCase.reusableViewClass, forCellReuseIdentifier: enumCase.rawValue)
+ tableView?.register(
+ enumCase.reusableViewClass,
+ forCellReuseIdentifier: enumCase.rawValue
+ )
}
HeaderFooterReuseIdentifiers.allCases.forEach { enumCase in
- tableView?.register(enumCase.reusableViewClass, forHeaderFooterViewReuseIdentifier: enumCase.rawValue)
+ tableView?.register(
+ enumCase.reusableViewClass,
+ forHeaderFooterViewReuseIdentifier: enumCase.rawValue
+ )
}
}
private func updateSnapshot() {
var newSnapshot = DataSourceSnapshot<Section, Item>()
newSnapshot.appendSections([.mullvadDNS, .customDNS])
- newSnapshot.appendItems([.blockAdvertising, .blockTracking, .blockMalware, .blockAdultContent, .blockGambling], in: .mullvadDNS)
+ newSnapshot.appendItems(
+ [.blockAdvertising, .blockTracking, .blockMalware, .blockAdultContent, .blockGambling],
+ in: .mullvadDNS
+ )
newSnapshot.appendItems([.useCustomDNS], in: .customDNS)
let dnsServerItems = viewModel.customDNSDomains.map { entry in
@@ -319,17 +353,24 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
}
newSnapshot.appendItems(dnsServerItems, in: .customDNS)
- if isEditing && viewModel.customDNSDomains.count < DNSSettings.maxAllowedCustomDNSDomains {
+ if isEditing, viewModel.customDNSDomains.count < DNSSettings.maxAllowedCustomDNSDomains {
newSnapshot.appendItems([.addDNSServer], in: .customDNS)
}
snapshot = newSnapshot
}
- private func dequeueCellForItem(_ item: Item, in tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
+ private func dequeueCellForItem(
+ _ item: Item,
+ in tableView: UITableView,
+ at indexPath: IndexPath
+ ) -> UITableViewCell {
switch item {
case .blockAdvertising:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"BLOCK_ADS_CELL_LABEL",
@@ -346,7 +387,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
case .blockTracking:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"BLOCK_TRACKERS_CELL_LABEL",
@@ -363,7 +407,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
case .blockMalware:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"BLOCK_MALWARE_CELL_LABEL",
@@ -380,7 +427,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
case .blockAdultContent:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"BLOCK_ADULT_CELL_LABEL",
@@ -397,7 +447,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
case .blockGambling:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"BLOCK_GAMBLING_CELL_LABEL",
@@ -414,7 +467,10 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
case .useCustomDNS:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue,
+ for: indexPath
+ ) as! SettingsSwitchCell
cell.titleLabel.text = NSLocalizedString(
"CUSTOM_DNS_CELL_LABEL",
@@ -428,12 +484,16 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
self?.setEnableCustomDNS(isOn)
}
- cell.accessibilityHint = viewModel.customDNSPrecondition.localizedDescription(isEditing: isEditing)
+ cell.accessibilityHint = viewModel.customDNSPrecondition
+ .localizedDescription(isEditing: isEditing)
return cell
case .addDNSServer:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.addDNSServer.rawValue, for: indexPath) as! SettingsAddDNSEntryCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.addDNSServer.rawValue,
+ for: indexPath
+ ) as! SettingsAddDNSEntryCell
cell.titleLabel.text = NSLocalizedString(
"ADD_CUSTOM_DNS_SERVER_CELL_LABEL",
tableName: "Preferences",
@@ -447,17 +507,23 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
return cell
- case .dnsServer(let entryIdentifier):
+ case let .dnsServer(entryIdentifier):
let dnsServerEntry = viewModel.dnsEntry(entryIdentifier: entryIdentifier)!
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.dnsServer.rawValue, for: indexPath) as! SettingsDNSTextCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.dnsServer.rawValue,
+ for: indexPath
+ ) as! SettingsDNSTextCell
cell.textField.text = dnsServerEntry.address
cell.isValidInput = viewModel.validateDNSDomainUserInput(dnsServerEntry.address)
cell.onTextChange = { [weak self] cell in
- guard let self = self, let indexPath = self.tableView?.indexPath(for: cell) else { return }
+ guard let self = self,
+ let indexPath = self.tableView?.indexPath(for: cell) else { return }
- if case .dnsServer(let entryIdentifier) = self.snapshot.itemForIndexPath(indexPath) {
+ if case let .dnsServer(entryIdentifier) = self.snapshot
+ .itemForIndexPath(indexPath)
+ {
self.handleDNSEntryChange(entryIdentifier: entryIdentifier, cell: cell)
}
}
@@ -581,14 +647,16 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
if completed {
// Focus on the new entry text field.
let lastDNSEntry = self.snapshot.items(in: .customDNS).last { item in
- if case .dnsServer(let entryIdentifier) = item {
+ if case let .dnsServer(entryIdentifier) = item {
return entryIdentifier == newDNSEntry.identifier
} else {
return false
}
}
- if let lastDNSEntry = lastDNSEntry, let indexPath = self.snapshot.indexPathForItem(lastDNSEntry) {
+ if let lastDNSEntry = lastDNSEntry,
+ let indexPath = self.snapshot.indexPathForItem(lastDNSEntry)
+ {
let cell = self.tableView?.cellForRow(at: indexPath) as? SettingsDNSTextCell
self.tableView?.scrollToRow(at: indexPath, at: .bottom, animated: true)
@@ -629,7 +697,9 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
// Reload footer view
tableView?.performBatchUpdates {
- if let reusableView = tableView?.footerView(forSection: sectionIndex) as? SettingsStaticTextFooterView {
+ if let reusableView = tableView?
+ .footerView(forSection: sectionIndex) as? SettingsStaticTextFooterView
+ {
configureFooterView(reusableView)
}
}
@@ -647,5 +717,4 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat
reusableView.titleLabel.attributedText = viewModel.customDNSPrecondition
.attributedLocalizedDescription(isEditing: isEditing, preferredFont: font)
}
-
}
diff --git a/ios/MullvadVPN/PreferencesDataSourceDelegate.swift b/ios/MullvadVPN/PreferencesDataSourceDelegate.swift
index 1de9aef42b..84f18d93e8 100644
--- a/ios/MullvadVPN/PreferencesDataSourceDelegate.swift
+++ b/ios/MullvadVPN/PreferencesDataSourceDelegate.swift
@@ -9,5 +9,8 @@
import Foundation
protocol PreferencesDataSourceDelegate: AnyObject {
- func preferencesDataSource(_ dataSource: PreferencesDataSource, didChangeViewModel viewModel: PreferencesViewModel)
+ func preferencesDataSource(
+ _ dataSource: PreferencesDataSource,
+ didChangeViewModel viewModel: PreferencesViewModel
+ )
}
diff --git a/ios/MullvadVPN/PreferencesViewController.swift b/ios/MullvadVPN/PreferencesViewController.swift
index 05fdb793fd..30edd298ba 100644
--- a/ios/MullvadVPN/PreferencesViewController.swift
+++ b/ios/MullvadVPN/PreferencesViewController.swift
@@ -6,11 +6,12 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
-class PreferencesViewController: UITableViewController, PreferencesDataSourceDelegate, TunnelObserver {
-
+class PreferencesViewController: UITableViewController, PreferencesDataSourceDelegate,
+ TunnelObserver
+{
private let dataSource = PreferencesDataSource()
override var preferredStatusBarStyle: UIStatusBarStyle {
@@ -65,7 +66,10 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel
// MARK: - PreferencesDataSourceDelegate
- func preferencesDataSource(_ dataSource: PreferencesDataSource, didChangeViewModel dataModel: PreferencesViewModel) {
+ func preferencesDataSource(
+ _ dataSource: PreferencesDataSource,
+ didChangeViewModel dataModel: PreferencesViewModel
+ ) {
let dnsSettings = dataModel.asDNSSettings()
TunnelManager.shared.setDNSSettings(dnsSettings)
@@ -85,13 +89,14 @@ class PreferencesViewController: UITableViewController, PreferencesDataSourceDel
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
dataSource.update(from: tunnelSettings.dnsSettings)
}
-
func tunnelManager(_ manager: TunnelManager, didUpdateDeviceState deviceState: DeviceState) {
// no-op
}
-
}
diff --git a/ios/MullvadVPN/PreferencesViewModel.swift b/ios/MullvadVPN/PreferencesViewModel.swift
index 123331f4a8..4a164dca84 100644
--- a/ios/MullvadVPN/PreferencesViewModel.swift
+++ b/ios/MullvadVPN/PreferencesViewModel.swift
@@ -27,7 +27,10 @@ enum CustomDNSPrecondition {
}
/// Returns attributed localized description explaining how to enable Custom DNS.
- func attributedLocalizedDescription(isEditing: Bool, preferredFont: UIFont) -> NSAttributedString? {
+ func attributedLocalizedDescription(
+ isEditing: Bool,
+ preferredFont: UIFont
+ ) -> NSAttributedString? {
switch self {
case .satisfied:
return nil
diff --git a/ios/MullvadVPN/ProblemReportReviewViewController.swift b/ios/MullvadVPN/ProblemReportReviewViewController.swift
index 19fc05a248..cbe2956746 100644
--- a/ios/MullvadVPN/ProblemReportReviewViewController.swift
+++ b/ios/MullvadVPN/ProblemReportReviewViewController.swift
@@ -9,12 +9,15 @@
import UIKit
class ProblemReportReviewViewController: UIViewController {
-
private var textView = UITextView()
private let reportString: String
private var dismissButtonItem: UIBarButtonItem {
- return UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDismissButton(_:)))
+ return UIBarButtonItem(
+ barButtonSystemItem: .done,
+ target: self,
+ action: #selector(handleDismissButton(_:))
+ )
}
init(reportString: String) {
@@ -51,7 +54,7 @@ class ProblemReportReviewViewController: UIViewController {
textView.topAnchor.constraint(equalTo: view.topAnchor),
textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- textView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ textView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
// Used to layout constraints so that navigation controller could properly adjust the text
diff --git a/ios/MullvadVPN/ProblemReportSubmissionOverlayView.swift b/ios/MullvadVPN/ProblemReportSubmissionOverlayView.swift
index fadff38f70..2274606044 100644
--- a/ios/MullvadVPN/ProblemReportSubmissionOverlayView.swift
+++ b/ios/MullvadVPN/ProblemReportSubmissionOverlayView.swift
@@ -6,11 +6,10 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Foundation
+import UIKit
class ProblemReportSubmissionOverlayView: UIView {
-
var editButtonAction: (() -> Void)?
var retryButtonAction: (() -> Void)?
@@ -49,7 +48,7 @@ class ProblemReportSubmissionOverlayView: UIView {
switch self {
case .sending:
return nil
- case .sent(let email):
+ case let .sent(email):
let combinedAttributedString = NSMutableAttributedString(
string: NSLocalizedString(
"THANKS_MESSAGE",
@@ -79,7 +78,8 @@ class ProblemReportSubmissionOverlayView: UIView {
tableName: "ProblemReport",
value: "If needed we will contact you at %@",
comment: ""
- ), email)
+ ), email
+ )
let emailAttributedString = NSMutableAttributedString(string: emailText)
if let emailRange = emailText.range(of: email) {
let font = UIFont.systemFont(ofSize: 17, weight: .bold)
@@ -94,7 +94,7 @@ class ProblemReportSubmissionOverlayView: UIView {
return combinedAttributedString
- case .failure(let error):
+ case let .failure(error):
return error.errorChainDescription.flatMap { NSAttributedString(string: $0) }
}
}
@@ -102,7 +102,7 @@ class ProblemReportSubmissionOverlayView: UIView {
var state: State = .sending {
didSet {
- transitionToState(self.state)
+ transitionToState(state)
}
}
@@ -111,6 +111,7 @@ class ProblemReportSubmissionOverlayView: UIView {
indicator.tintColor = .white
return indicator
}()
+
let statusImageView = StatusImageView(style: .success)
let titleLabel: UILabel = {
@@ -179,13 +180,22 @@ class ProblemReportSubmissionOverlayView: UIView {
}
private func addSubviews() {
- for subview in [titleLabel, bodyLabel, activityIndicator, statusImageView, buttonsStackView] {
+ for subview in [
+ titleLabel,
+ bodyLabel,
+ activityIndicator,
+ statusImageView,
+ buttonsStackView,
+ ] {
subview.translatesAutoresizingMaskIntoConstraints = false
addSubview(subview)
}
NSLayoutConstraint.activate([
- statusImageView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 32),
+ statusImageView.topAnchor.constraint(
+ equalTo: layoutMarginsGuide.topAnchor,
+ constant: 32
+ ),
statusImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
activityIndicator.centerXAnchor.constraint(equalTo: statusImageView.centerXAnchor),
@@ -195,14 +205,20 @@ class ProblemReportSubmissionOverlayView: UIView {
titleLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
titleLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- bodyLabel.topAnchor.constraint(equalToSystemSpacingBelow: titleLabel.bottomAnchor, multiplier: 1),
+ bodyLabel.topAnchor.constraint(
+ equalToSystemSpacingBelow: titleLabel.bottomAnchor,
+ multiplier: 1
+ ),
bodyLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
bodyLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonsStackView.topAnchor.constraint(greaterThanOrEqualTo: bodyLabel.bottomAnchor, constant: 18),
+ buttonsStackView.topAnchor.constraint(
+ greaterThanOrEqualTo: bodyLabel.bottomAnchor,
+ constant: 18
+ ),
buttonsStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
buttonsStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonsStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ buttonsStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
])
}
diff --git a/ios/MullvadVPN/ProblemReportViewController.swift b/ios/MullvadVPN/ProblemReportViewController.swift
index 0087faa18f..a48da7ba24 100644
--- a/ios/MullvadVPN/ProblemReportViewController.swift
+++ b/ios/MullvadVPN/ProblemReportViewController.swift
@@ -9,7 +9,6 @@
import UIKit
class ProblemReportViewController: UIViewController, UITextFieldDelegate, ConditionalNavigation {
-
private let apiProxy = REST.ProxyFactory.shared.createAPIProxy()
private var textViewKeyboardResponder: AutomaticKeyboardResponder?
@@ -167,13 +166,15 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
return button
}()
- private lazy var emailAccessoryToolbar: UIToolbar = {
- return makeKeyboardToolbar(canGoBackward: false, canGoForward: true)
- }()
+ private lazy var emailAccessoryToolbar: UIToolbar = makeKeyboardToolbar(
+ canGoBackward: false,
+ canGoForward: true
+ )
- private lazy var messageAccessoryToolbar: UIToolbar = {
- return makeKeyboardToolbar(canGoBackward: true, canGoForward: false)
- }()
+ private lazy var messageAccessoryToolbar: UIToolbar = makeKeyboardToolbar(
+ canGoBackward: true,
+ canGoForward: false
+ )
private lazy var submissionOverlayView: ProblemReportSubmissionOverlayView = {
let overlay = ProblemReportSubmissionOverlayView()
@@ -246,8 +247,8 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
override func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
- self.scrollViewKeyboardResponder?.updateContentInsets()
- self.textViewKeyboardResponder?.updateContentInsets()
+ scrollViewKeyboardResponder?.updateContentInsets()
+ textViewKeyboardResponder?.updateContentInsets()
}
// MARK: - Actions
@@ -270,7 +271,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
}
if Self.persistentViewModel.email.isEmpty {
- presentEmptyEmailConfirmationAlert { (shouldSend) in
+ presentEmptyEmailConfirmationAlert { shouldSend in
if shouldSend {
proceedWithSubmission()
}
@@ -281,7 +282,10 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
}
@objc func handleViewLogsButtonTap() {
- let reviewController = ProblemReportReviewViewController(reportString: consolidatedLog.string)
+ let reviewController = ProblemReportReviewViewController(
+ reportString: consolidatedLog
+ .string
+ )
let navigationController = UINavigationController(rootViewController: reviewController)
present(navigationController, animated: true)
@@ -291,22 +295,34 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
private func registerForNotifications() {
let notificationCenter = NotificationCenter.default
- notificationCenter.addObserver(self, selector: #selector(emailTextFieldDidChange),
- name: UITextField.textDidChangeNotification,
- object: emailTextField)
- notificationCenter.addObserver(self, selector: #selector(messageTextViewDidBeginEditing),
- name: UITextView.textDidBeginEditingNotification,
- object: messageTextView)
- notificationCenter.addObserver(self, selector: #selector(messageTextViewDidEndEditing),
- name: UITextView.textDidEndEditingNotification,
- object: messageTextView)
- notificationCenter.addObserver(self, selector: #selector(messageTextViewDidChange),
- name: UITextView.textDidChangeNotification,
- object: messageTextView)
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(emailTextFieldDidChange),
+ name: UITextField.textDidChangeNotification,
+ object: emailTextField
+ )
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(messageTextViewDidBeginEditing),
+ name: UITextView.textDidBeginEditingNotification,
+ object: messageTextView
+ )
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(messageTextViewDidEndEditing),
+ name: UITextView.textDidEndEditingNotification,
+ object: messageTextView
+ )
+ notificationCenter.addObserver(
+ self,
+ selector: #selector(messageTextViewDidChange),
+ name: UITextView.textDidChangeNotification,
+ object: messageTextView
+ )
}
private func makeKeyboardToolbar(canGoBackward: Bool, canGoForward: Bool) -> UIToolbar {
- var toolbarItems = UIBarButtonItem.makeKeyboardNavigationItems { (prevButton, nextButton) in
+ var toolbarItems = UIBarButtonItem.makeKeyboardNavigationItems { prevButton, nextButton in
prevButton.target = self
prevButton.action = #selector(focusEmailTextField)
prevButton.isEnabled = canGoBackward
@@ -318,7 +334,11 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
toolbarItems.append(contentsOf: [
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
- UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissKeyboard))
+ UIBarButtonItem(
+ barButtonSystemItem: .done,
+ target: self,
+ action: #selector(dismissKeyboard)
+ ),
])
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
@@ -327,39 +347,59 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
}
private func addConstraints() {
- self.activeMessageTextViewConstraints = [
+ activeMessageTextViewConstraints = [
messageTextView.topAnchor.constraint(equalTo: view.topAnchor),
messageTextView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
messageTextView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
messageTextView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
]
- self.inactiveMessageTextViewConstraints = [
- messageTextView.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 12),
+ inactiveMessageTextViewConstraints = [
+ messageTextView.topAnchor.constraint(
+ equalTo: emailTextField.bottomAnchor,
+ constant: 12
+ ),
messageTextView.leadingAnchor.constraint(equalTo: textFieldsHolder.leadingAnchor),
messageTextView.trailingAnchor.constraint(equalTo: textFieldsHolder.trailingAnchor),
messageTextView.bottomAnchor.constraint(equalTo: textFieldsHolder.bottomAnchor),
]
var constraints = [
- subheaderLabel.topAnchor.constraint(equalTo: containerView.layoutMarginsGuide.topAnchor),
- subheaderLabel.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
- subheaderLabel.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
+ subheaderLabel.topAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.topAnchor),
+ subheaderLabel.leadingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
+ subheaderLabel.trailingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
- textFieldsHolder.topAnchor.constraint(equalTo: subheaderLabel.bottomAnchor, constant: 24),
- textFieldsHolder.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
- textFieldsHolder.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
+ textFieldsHolder.topAnchor.constraint(
+ equalTo: subheaderLabel.bottomAnchor,
+ constant: 24
+ ),
+ textFieldsHolder.leadingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
+ textFieldsHolder.trailingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
- buttonsStackView.topAnchor.constraint(equalTo: textFieldsHolder.bottomAnchor, constant: 18),
- buttonsStackView.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
- buttonsStackView.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
- buttonsStackView.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor),
+ buttonsStackView.topAnchor.constraint(
+ equalTo: textFieldsHolder.bottomAnchor,
+ constant: 18
+ ),
+ buttonsStackView.leadingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor),
+ buttonsStackView.trailingAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor),
+ buttonsStackView.bottomAnchor
+ .constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor),
emailTextField.topAnchor.constraint(equalTo: textFieldsHolder.topAnchor),
emailTextField.leadingAnchor.constraint(equalTo: textFieldsHolder.leadingAnchor),
emailTextField.trailingAnchor.constraint(equalTo: textFieldsHolder.trailingAnchor),
- messagePlaceholder.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 12),
+ messagePlaceholder.topAnchor.constraint(
+ equalTo: emailTextField.bottomAnchor,
+ constant: 12
+ ),
messagePlaceholder.leadingAnchor.constraint(equalTo: textFieldsHolder.leadingAnchor),
messagePlaceholder.trailingAnchor.constraint(equalTo: textFieldsHolder.trailingAnchor),
messagePlaceholder.bottomAnchor.constraint(equalTo: textFieldsHolder.bottomAnchor),
@@ -371,44 +411,49 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
scrollView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.contentLayoutGuide.topAnchor.constraint(equalTo: containerView.topAnchor),
- scrollView.contentLayoutGuide.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
- scrollView.contentLayoutGuide.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
- scrollView.contentLayoutGuide.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
+ scrollView.contentLayoutGuide.bottomAnchor
+ .constraint(equalTo: containerView.bottomAnchor),
+ scrollView.contentLayoutGuide.leadingAnchor
+ .constraint(equalTo: containerView.leadingAnchor),
+ scrollView.contentLayoutGuide.trailingAnchor
+ .constraint(equalTo: containerView.trailingAnchor),
- scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
- scrollView.contentLayoutGuide.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.heightAnchor),
+ scrollView.contentLayoutGuide.widthAnchor
+ .constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
+ scrollView.contentLayoutGuide.heightAnchor
+ .constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.heightAnchor),
messageTextView.heightAnchor.constraint(greaterThanOrEqualToConstant: 150),
]
- constraints.append(contentsOf: self.inactiveMessageTextViewConstraints)
+ constraints.append(contentsOf: inactiveMessageTextViewConstraints)
NSLayoutConstraint.activate(constraints)
}
private func setDescriptionFieldExpanded(_ isExpanded: Bool) {
// Make voice over ignore siblings when expanded
- self.messageTextView.accessibilityViewIsModal = isExpanded
+ messageTextView.accessibilityViewIsModal = isExpanded
if isExpanded {
// Disable the large title
- self.navigationItem.largeTitleDisplayMode = .never
+ navigationItem.largeTitleDisplayMode = .never
// Move the text view above scroll view
- view.addSubview(self.messageTextView)
+ view.addSubview(messageTextView)
// Re-add old constraints
- NSLayoutConstraint.activate(self.inactiveMessageTextViewConstraints)
+ NSLayoutConstraint.activate(inactiveMessageTextViewConstraints)
// Do a layout pass
view.layoutIfNeeded()
// Swap constraints
- NSLayoutConstraint.deactivate(self.inactiveMessageTextViewConstraints)
- NSLayoutConstraint.activate(self.activeMessageTextViewConstraints)
+ NSLayoutConstraint.deactivate(inactiveMessageTextViewConstraints)
+ NSLayoutConstraint.activate(activeMessageTextViewConstraints)
// Enable content inset adjustment on text view
- self.messageTextView.contentInsetAdjustmentBehavior = .always
+ messageTextView.contentInsetAdjustmentBehavior = .always
// Animate constraints & rounded corners on the text view
animateDescriptionTextView(animations: {
@@ -416,7 +461,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
self.messageTextView.roundCorners = false
self.view.layoutIfNeeded()
- }) { (completed) in
+ }) { completed in
self.isMessageTextViewExpanded = true
self.textViewKeyboardResponder?.updateContentInsets()
@@ -427,11 +472,11 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
} else {
// Re-enable the large title
- self.navigationItem.largeTitleDisplayMode = .automatic
+ navigationItem.largeTitleDisplayMode = .automatic
// Swap constraints
- NSLayoutConstraint.deactivate(self.activeMessageTextViewConstraints)
- NSLayoutConstraint.activate(self.inactiveMessageTextViewConstraints)
+ NSLayoutConstraint.deactivate(activeMessageTextViewConstraints)
+ NSLayoutConstraint.activate(inactiveMessageTextViewConstraints)
// Animate constraints & rounded corners on the text view
animateDescriptionTextView(animations: {
@@ -439,7 +484,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
self.messageTextView.roundCorners = true
self.view.layoutIfNeeded()
- }) { (completed) in
+ }) { completed in
// Revert the content adjustment behavior
self.messageTextView.contentInsetAdjustmentBehavior = .never
@@ -454,8 +499,11 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
}
}
- private func animateDescriptionTextView(animations: @escaping () -> Void, completion: @escaping (Bool) -> Void) {
- UIView.animate(withDuration: 0.25, animations: animations) { (completed) in
+ private func animateDescriptionTextView(
+ animations: @escaping () -> Void,
+ completion: @escaping (Bool) -> Void
+ ) {
+ UIView.animate(withDuration: 0.25, animations: animations) { completed in
completion(completed)
}
}
@@ -468,7 +516,11 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
comment: ""
)
- let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
+ let alertController = UIAlertController(
+ title: nil,
+ message: message,
+ preferredStyle: .alert
+ )
let cancelAction = UIAlertAction(
title: NSLocalizedString(
@@ -506,18 +558,26 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
private func showSubmissionOverlay() {
guard !showsSubmissionOverlay else { return }
- self.showsSubmissionOverlay = true
+ showsSubmissionOverlay = true
view.addSubview(submissionOverlayView)
NSLayoutConstraint.activate([
submissionOverlayView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
- submissionOverlayView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
- submissionOverlayView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
- submissionOverlayView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
+ submissionOverlayView.leadingAnchor
+ .constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
+ submissionOverlayView.trailingAnchor
+ .constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
+ submissionOverlayView.bottomAnchor
+ .constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
- UIView.transition(from: scrollView, to: submissionOverlayView, duration: 0.25, options: [.showHideTransitionViews, .transitionCrossDissolve]) { (success) in
+ UIView.transition(
+ from: scrollView,
+ to: submissionOverlayView,
+ duration: 0.25,
+ options: [.showHideTransitionViews, .transitionCrossDissolve]
+ ) { success in
// success
}
}
@@ -525,9 +585,14 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
private func hideSubmissionOverlay() {
guard showsSubmissionOverlay else { return }
- self.showsSubmissionOverlay = false
+ showsSubmissionOverlay = false
- UIView.transition(from: submissionOverlayView, to: scrollView, duration: 0.25, options: [.showHideTransitionViews, .transitionCrossDissolve]) { (success) in
+ UIView.transition(
+ from: submissionOverlayView,
+ to: scrollView,
+ duration: 0.25,
+ options: [.showHideTransitionViews, .transitionCrossDissolve]
+ ) { success in
// success
self.submissionOverlayView.removeFromSuperview()
}
@@ -591,7 +656,10 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
navigationItem.setHidesBackButton(true, animated: true)
}
- private func didSendProblemReport(viewModel: ViewModel, completion: OperationCompletion<(), REST.Error>) {
+ private func didSendProblemReport(
+ viewModel: ViewModel,
+ completion: OperationCompletion<Void, REST.Error>
+ ) {
switch completion {
case .success:
submissionOverlayView.state = .sent(viewModel.email)
@@ -599,7 +667,7 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
// Clear persistent view model upon successful submission
clearPersistentViewModel()
- case .failure(let error):
+ case let .failure(error):
submissionOverlayView.state = .failure(error)
case .cancelled:
@@ -615,11 +683,16 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
let viewModel = Self.persistentViewModel
let log = consolidatedLog.string
- let metadata = consolidatedLog.metadata.reduce(into: [:]) { (output, entry) in
+ let metadata = consolidatedLog.metadata.reduce(into: [:]) { output, entry in
output[entry.key.rawValue] = entry.value
}
- let request = REST.ProblemReportRequest(address: viewModel.email, message: viewModel.message, log: log, metadata: metadata)
+ let request = REST.ProblemReportRequest(
+ address: viewModel.email,
+ message: viewModel.message,
+ log: log,
+ metadata: metadata
+ )
willSendProblemReport()
@@ -655,7 +728,10 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
// MARK: - ConditionalNavigation
- func shouldPopNavigationItem(_ navigationItem: UINavigationItem, trigger: NavigationPopTrigger) -> Bool {
+ func shouldPopNavigationItem(
+ _ navigationItem: UINavigationItem,
+ trigger: NavigationPopTrigger
+ ) -> Bool {
switch trigger {
case .interactiveGesture:
// Disable swipe when editing
@@ -667,5 +743,4 @@ class ProblemReportViewController: UIViewController, UITextFieldDelegate, Condit
return true
}
}
-
}
diff --git a/ios/MullvadVPN/REST/HTTP.swift b/ios/MullvadVPN/REST/HTTP.swift
index 82178dc2f5..85995c43ce 100644
--- a/ios/MullvadVPN/REST/HTTP.swift
+++ b/ios/MullvadVPN/REST/HTTP.swift
@@ -27,7 +27,7 @@ struct HTTPStatus: RawRepresentable, Equatable {
static let notFound = HTTPStatus(rawValue: 404)
static func isSuccess(_ code: Int) -> Bool {
- return (200..<300).contains(code)
+ return (200 ..< 300).contains(code)
}
let rawValue: Int
@@ -54,7 +54,7 @@ extension HTTPURLResponse {
if #available(iOS 13.0, *) {
return self.value(forHTTPHeaderField: headerField)
} else {
- for case let key as String in self.allHeaderFields.keys {
+ for case let key as String in allHeaderFields.keys {
if case .orderedSame = key.caseInsensitiveCompare(headerField) {
return self.allHeaderFields[key] as? String
}
diff --git a/ios/MullvadVPN/REST/RESTAPIProxy.swift b/ios/MullvadVPN/REST/RESTAPIProxy.swift
index 1d7f259b4b..a53b95b8ac 100644
--- a/ios/MullvadVPN/REST/RESTAPIProxy.swift
+++ b/ios/MullvadVPN/REST/RESTAPIProxy.swift
@@ -8,8 +8,8 @@
import Foundation
import Network
-import class WireGuardKitTypes.PublicKey
import struct WireGuardKitTypes.IPAddressRange
+import class WireGuardKitTypes.PublicKey
extension REST {
class APIProxy: Proxy<ProxyConfiguration> {
@@ -28,8 +28,7 @@ extension REST {
func getAddressList(
retryStrategy: REST.RetryStrategy,
completionHandler: @escaping CompletionHandler<[AnyIPEndpoint]>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler { endpoint in
return try self.requestFactory.createRequest(
endpoint: endpoint,
@@ -56,8 +55,7 @@ extension REST {
etag: String?,
retryStrategy: REST.RetryStrategy,
completionHandler: @escaping CompletionHandler<ServerRelaysCacheResponse>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler { endpoint in
var requestBuilder = try self.requestFactory.createRequestBuilder(
endpoint: endpoint,
@@ -72,33 +70,35 @@ extension REST {
return requestBuilder.getRequest()
}
- let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<ServerRelaysCacheResponse> in
- let httpStatus = HTTPStatus(rawValue: response.statusCode)
+ let responseHandler =
+ AnyResponseHandler { response, data -> ResponseHandlerResult<ServerRelaysCacheResponse> in
+ let httpStatus = HTTPStatus(rawValue: response.statusCode)
- switch httpStatus {
- case let httpStatus where httpStatus.isSuccess:
- return .decoding {
- let serverRelays = try self.responseDecoder.decode(
- ServerRelaysResponse.self,
- from: data
- )
- let newEtag = response.value(forCaseInsensitiveHTTPHeaderField: HTTPHeader.etag)
+ switch httpStatus {
+ case let httpStatus where httpStatus.isSuccess:
+ return .decoding {
+ let serverRelays = try self.responseDecoder.decode(
+ ServerRelaysResponse.self,
+ from: data
+ )
+ let newEtag = response
+ .value(forCaseInsensitiveHTTPHeaderField: HTTPHeader.etag)
- return .newContent(newEtag, serverRelays)
- }
+ return .newContent(newEtag, serverRelays)
+ }
- case .notModified where etag != nil:
- return .success(.notModified)
+ case .notModified where etag != nil:
+ return .success(.notModified)
- default:
- return .unhandledResponse(
- try? self.responseDecoder.decode(
- ServerErrorResponse.self,
- from: data
+ default:
+ return .unhandledResponse(
+ try? self.responseDecoder.decode(
+ ServerErrorResponse.self,
+ from: data
+ )
)
- )
+ }
}
- }
return addOperation(
name: "get-relays",
@@ -114,8 +114,7 @@ extension REST {
receiptString: Data,
retryStrategy: REST.RetryStrategy,
completionHandler: @escaping CompletionHandler<CreateApplePaymentResponse>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler { endpoint in
var requestBuilder = try self.requestFactory
.createRequestBuilder(
@@ -133,28 +132,32 @@ extension REST {
return requestBuilder.getRequest()
}
- let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<CreateApplePaymentResponse> in
- if HTTPStatus.isSuccess(response.statusCode) {
- return .decoding {
- let serverResponse = try self.responseDecoder.decode(
- CreateApplePaymentRawResponse.self,
- from: data
- )
- if serverResponse.timeAdded > 0 {
- return .timeAdded(serverResponse.timeAdded, serverResponse.newExpiry)
- } else {
- return .noTimeAdded(serverResponse.newExpiry)
+ let responseHandler =
+ AnyResponseHandler { response, data -> ResponseHandlerResult<CreateApplePaymentResponse> in
+ if HTTPStatus.isSuccess(response.statusCode) {
+ return .decoding {
+ let serverResponse = try self.responseDecoder.decode(
+ CreateApplePaymentRawResponse.self,
+ from: data
+ )
+ if serverResponse.timeAdded > 0 {
+ return .timeAdded(
+ serverResponse.timeAdded,
+ serverResponse.newExpiry
+ )
+ } else {
+ return .noTimeAdded(serverResponse.newExpiry)
+ }
}
- }
- } else {
- return .unhandledResponse(
- try? self.responseDecoder.decode(
- ServerErrorResponse.self,
- from: data
+ } else {
+ return .unhandledResponse(
+ try? self.responseDecoder.decode(
+ ServerErrorResponse.self,
+ from: data
+ )
)
- )
+ }
}
- }
return addOperation(
name: "create-apple-payment",
@@ -169,8 +172,7 @@ extension REST {
_ body: ProblemReportRequest,
retryStrategy: REST.RetryStrategy,
completionHandler: @escaping CompletionHandler<Void>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler { endpoint in
var requestBuilder = try self.requestFactory.createRequestBuilder(
endpoint: endpoint,
@@ -183,18 +185,19 @@ extension REST {
return requestBuilder.getRequest()
}
- let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<Void> in
- if HTTPStatus.isSuccess(response.statusCode) {
- return .success(())
- } else {
- return .unhandledResponse(
- try? self.responseDecoder.decode(
- ServerErrorResponse.self,
- from: data
+ let responseHandler =
+ AnyResponseHandler { response, data -> ResponseHandlerResult<Void> in
+ if HTTPStatus.isSuccess(response.statusCode) {
+ return .success(())
+ } else {
+ return .unhandledResponse(
+ try? self.responseDecoder.decode(
+ ServerErrorResponse.self,
+ from: data
+ )
)
- )
+ }
}
- }
return addOperation(
name: "send-problem-report",
@@ -223,7 +226,7 @@ extension REST {
var newExpiry: Date {
switch self {
- case .noTimeAdded(let expiry), .timeAdded(_, let expiry):
+ case let .noTimeAdded(expiry), let .timeAdded(_, expiry):
return expiry
}
}
@@ -232,7 +235,7 @@ extension REST {
switch self {
case .noTimeAdded:
return 0
- case .timeAdded(let timeAdded, _):
+ case let .timeAdded(timeAdded, _):
return TimeInterval(timeAdded)
}
}
@@ -258,5 +261,4 @@ extension REST {
let log: String
let metadata: [String: String]
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTAccessTokenManager.swift b/ios/MullvadVPN/REST/RESTAccessTokenManager.swift
index eb124ae829..7d46b16edd 100644
--- a/ios/MullvadVPN/REST/RESTAccessTokenManager.swift
+++ b/ios/MullvadVPN/REST/RESTAccessTokenManager.swift
@@ -10,7 +10,6 @@ import Foundation
import Logging
extension REST {
-
final class AccessTokenManager {
private let logger = Logger(label: "REST.AccessTokenManager")
private let operationQueue = AsyncOperationQueue()
@@ -28,9 +27,9 @@ extension REST {
func getAccessToken(
accountNumber: String,
retryStrategy: REST.RetryStrategy,
- completionHandler: @escaping (OperationCompletion<REST.AccessTokenData, REST.Error>) -> Void
- ) -> Cancellable
- {
+ completionHandler: @escaping (OperationCompletion<REST.AccessTokenData, REST.Error>)
+ -> Void
+ ) -> Cancellable {
let operation = ResultBlockOperation<REST.AccessTokenData, REST.Error>(
dispatchQueue: dispatchQueue
) { operation in
@@ -45,11 +44,14 @@ extension REST {
) { completion in
self.dispatchQueue.async {
switch completion {
- case .success(let tokenData):
+ case let .success(tokenData):
self.tokens[accountNumber] = tokenData
- case .failure(let error):
- self.logger.error(chainedError: error, message: "Failed to fetch access token.")
+ case let .failure(error):
+ self.logger.error(
+ chainedError: error,
+ message: "Failed to fetch access token."
+ )
case .cancelled:
break
@@ -72,5 +74,4 @@ extension REST {
return operation
}
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTAccountsProxy.swift b/ios/MullvadVPN/REST/RESTAccountsProxy.swift
index e9c44f0f63..ace82fafb5 100644
--- a/ios/MullvadVPN/REST/RESTAccountsProxy.swift
+++ b/ios/MullvadVPN/REST/RESTAccountsProxy.swift
@@ -52,8 +52,7 @@ extension REST {
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<AccountData>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler(
createURLRequest: { endpoint, authorization in
var requestBuilder = try self.requestFactory.createRequestBuilder(
diff --git a/ios/MullvadVPN/REST/RESTAuthenticationProxy.swift b/ios/MullvadVPN/REST/RESTAuthenticationProxy.swift
index a9843ab750..5dda90f543 100644
--- a/ios/MullvadVPN/REST/RESTAuthenticationProxy.swift
+++ b/ios/MullvadVPN/REST/RESTAuthenticationProxy.swift
@@ -26,8 +26,7 @@ extension REST {
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<AccessTokenData>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler { endpoint in
var requestBuilder = try self.requestFactory.createRequestBuilder(
endpoint: endpoint,
diff --git a/ios/MullvadVPN/REST/RESTAuthorization.swift b/ios/MullvadVPN/REST/RESTAuthorization.swift
index 864cdb83a6..e97c42e732 100644
--- a/ios/MullvadVPN/REST/RESTAuthorization.swift
+++ b/ios/MullvadVPN/REST/RESTAuthorization.swift
@@ -25,7 +25,11 @@ extension REST {
private let accountNumber: String
private let retryStrategy: REST.RetryStrategy
- init(accessTokenManager: AccessTokenManager, accountNumber: String, retryStrategy: REST.RetryStrategy) {
+ init(
+ accessTokenManager: AccessTokenManager,
+ accountNumber: String,
+ retryStrategy: REST.RetryStrategy
+ ) {
self.accessTokenManager = accessTokenManager
self.accountNumber = accountNumber
self.retryStrategy = retryStrategy
diff --git a/ios/MullvadVPN/REST/RESTDevicesProxy.swift b/ios/MullvadVPN/REST/RESTDevicesProxy.swift
index 7ee34c0a8e..871785745b 100644
--- a/ios/MullvadVPN/REST/RESTDevicesProxy.swift
+++ b/ios/MullvadVPN/REST/RESTDevicesProxy.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import class WireGuardKitTypes.PublicKey
import struct WireGuardKitTypes.IPAddressRange
+import class WireGuardKitTypes.PublicKey
extension REST {
class DevicesProxy: Proxy<AuthProxyConfiguration> {
@@ -31,8 +31,7 @@ extension REST {
identifier: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<Device>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler(
createURLRequest: { endpoint, authorization in
var path: URLPathTemplate = "devices/{id}"
@@ -59,22 +58,23 @@ extension REST {
)
)
- let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<Device> in
- let httpStatus = HTTPStatus(rawValue: response.statusCode)
+ let responseHandler =
+ AnyResponseHandler { response, data -> ResponseHandlerResult<Device> in
+ let httpStatus = HTTPStatus(rawValue: response.statusCode)
- if httpStatus.isSuccess {
- return .decoding {
- return try self.responseDecoder.decode(Device.self, from: data)
- }
- } else {
- return .unhandledResponse(
- try? self.responseDecoder.decode(
- ServerErrorResponse.self,
- from: data
+ if httpStatus.isSuccess {
+ return .decoding {
+ return try self.responseDecoder.decode(Device.self, from: data)
+ }
+ } else {
+ return .unhandledResponse(
+ try? self.responseDecoder.decode(
+ ServerErrorResponse.self,
+ from: data
+ )
)
- )
+ }
}
- }
return addOperation(
name: "get-device",
@@ -90,8 +90,7 @@ extension REST {
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<[Device]>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler(
createURLRequest: { endpoint, authorization in
var requestBuilder = try self.requestFactory.createRequestBuilder(
@@ -132,8 +131,7 @@ extension REST {
request: CreateDeviceRequest,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<Device>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler(
createURLRequest: { endpoint, authorization in
var requestBuilder = try self.requestFactory.createRequestBuilder(
@@ -175,8 +173,7 @@ extension REST {
identifier: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping CompletionHandler<Bool>
- ) -> Cancellable
- {
+ ) -> Cancellable {
let requestHandler = AnyRequestHandler(
createURLRequest: { endpoint, authorization in
var path: URLPathTemplate = "devices/{id}"
@@ -204,25 +201,26 @@ extension REST {
)
)
- let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<Bool> in
- let statusCode = HTTPStatus(rawValue: response.statusCode)
+ let responseHandler =
+ AnyResponseHandler { response, data -> ResponseHandlerResult<Bool> in
+ let statusCode = HTTPStatus(rawValue: response.statusCode)
- switch statusCode {
- case let statusCode where statusCode.isSuccess:
- return .success(true)
+ switch statusCode {
+ case let statusCode where statusCode.isSuccess:
+ return .success(true)
- case .notFound:
- return .success(false)
+ case .notFound:
+ return .success(false)
- default:
- return .unhandledResponse(
- try? self.responseDecoder.decode(
- ServerErrorResponse.self,
- from: data
+ default:
+ return .unhandledResponse(
+ try? self.responseDecoder.decode(
+ ServerErrorResponse.self,
+ from: data
+ )
)
- )
+ }
}
- }
return addOperation(
name: "delete-device",
@@ -288,7 +286,6 @@ extension REST {
completionHandler: completion
)
}
-
}
struct CreateDeviceRequest: Encodable {
@@ -341,5 +338,4 @@ extension REST {
struct Port: Decodable {
let id: String
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTError.swift b/ios/MullvadVPN/REST/RESTError.swift
index 44db332050..25e51bd1b9 100644
--- a/ios/MullvadVPN/REST/RESTError.swift
+++ b/ios/MullvadVPN/REST/RESTError.swift
@@ -9,7 +9,6 @@
import Foundation
extension REST {
-
/// An error type returned by REST API classes.
enum Error: ChainedError {
/// A failure to create URL request.
@@ -30,7 +29,7 @@ extension REST {
return "Failure to create URL request."
case .network:
return "Network error."
- case .unhandledResponse(let statusCode, let serverResponse):
+ case let .unhandledResponse(statusCode, serverResponse):
var str = "Failure to handle server response: HTTP/\(statusCode)."
if let code = serverResponse?.code {
@@ -48,7 +47,7 @@ extension REST {
}
func compareErrorCode(_ code: ServerResponseCode) -> Bool {
- if case .unhandledResponse(_, let serverResponse) = self {
+ if case let .unhandledResponse(_, serverResponse) = self {
return serverResponse?.code == code
} else {
return false
@@ -88,5 +87,4 @@ extension REST {
self.rawValue = rawValue
}
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTNetworkOperation.swift b/ios/MullvadVPN/REST/RESTNetworkOperation.swift
index 0032d4f904..02b1f5bff2 100644
--- a/ios/MullvadVPN/REST/RESTNetworkOperation.swift
+++ b/ios/MullvadVPN/REST/RESTNetworkOperation.swift
@@ -36,16 +36,15 @@ extension REST {
requestHandler: AnyRequestHandler,
responseHandler: AnyResponseHandler<Success>,
completionHandler: @escaping CompletionHandler
- )
- {
- self.urlSession = configuration.session
- self.addressCacheStore = configuration.addressCacheStore
+ ) {
+ urlSession = configuration.session
+ addressCacheStore = configuration.addressCacheStore
self.retryStrategy = retryStrategy
self.requestHandler = requestHandler
self.responseHandler = responseHandler
var logger = Logger(label: "REST.NetworkOperation")
- logger[metadataKey: "name"] = .string(name)
+ logger[metadataKey: "name"] = .string(name)
self.logger = logger
super.init(
@@ -87,10 +86,10 @@ extension REST {
authorizationTask = authorizationProvider.getAuthorization { completion in
self.dispatchQueue.async {
switch completion {
- case .success(let authorization):
+ case let .success(authorization):
self.didReceiveAuthorization(authorization)
- case .failure(let error):
+ case let .failure(error):
self.didFailToRequestAuthorization(error)
case .cancelled:
@@ -108,7 +107,7 @@ extension REST {
return
}
- let endpoint = self.addressCacheStore.getCurrentEndpoint()
+ let endpoint = addressCacheStore.getCurrentEndpoint()
do {
let request = try requestHandler.createURLRequest(
@@ -136,24 +135,28 @@ extension REST {
private func didReceiveURLRequest(_ restRequest: REST.Request, endpoint: AnyIPEndpoint) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
- logger.debug("Send request to \(restRequest.pathTemplate.templateString) via \(endpoint).")
+ logger
+ .debug(
+ "Send request to \(restRequest.pathTemplate.templateString) via \(endpoint)."
+ )
- networkTask = urlSession.dataTask(with: restRequest.urlRequest) { [weak self] data, response, error in
- guard let self = self else { return }
+ networkTask = urlSession
+ .dataTask(with: restRequest.urlRequest) { [weak self] data, response, error in
+ guard let self = self else { return }
- self.dispatchQueue.async {
- if let error = error {
- let urlError = error as! URLError
+ self.dispatchQueue.async {
+ if let error = error {
+ let urlError = error as! URLError
- self.didReceiveURLError(urlError, endpoint: endpoint)
- } else {
- let httpResponse = response as! HTTPURLResponse
- let data = data ?? Data()
+ self.didReceiveURLError(urlError, endpoint: endpoint)
+ } else {
+ let httpResponse = response as! HTTPURLResponse
+ let data = data ?? Data()
- self.didReceiveURLResponse(httpResponse, data: data, endpoint: endpoint)
+ self.didReceiveURLResponse(httpResponse, data: data, endpoint: endpoint)
+ }
}
}
- }
networkTask?.resume()
}
@@ -225,7 +228,11 @@ extension REST {
retryTimer = timer
}
- private func didReceiveURLResponse(_ response: HTTPURLResponse, data: Data, endpoint: AnyIPEndpoint) {
+ private func didReceiveURLResponse(
+ _ response: HTTPURLResponse,
+ data: Data,
+ endpoint: AnyIPEndpoint
+ ) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
logger.debug("Response: \(response.statusCode).")
@@ -233,11 +240,11 @@ extension REST {
let handlerResult = responseHandler.handleURLResponse(response, data: data)
switch handlerResult {
- case .success(let output):
+ case let .success(output):
// Response handler produced value.
finish(completion: .success(output))
- case .decoding(let decoderBlock):
+ case let .decoding(decoderBlock):
// Response handler returned a block decoding value.
let decodeResult = Result { try decoderBlock() }
.mapError { error -> REST.Error in
@@ -245,11 +252,11 @@ extension REST {
}
finish(completion: OperationCompletion(result: decodeResult))
- case .unhandledResponse(let serverErrorResponse):
+ case let .unhandledResponse(serverErrorResponse):
// Response handler couldn't handle the response.
if serverErrorResponse?.code == .invalidAccessToken,
- requiresAuthorization,
- retryInvalidAccessTokenError
+ requiresAuthorization,
+ retryInvalidAccessTokenError
{
logger.debug("Received invalid access token error. Retry once.")
retryInvalidAccessTokenError = false
@@ -264,5 +271,4 @@ extension REST {
}
}
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTProxy.swift b/ios/MullvadVPN/REST/RESTProxy.swift
index 5ef15bff86..1030133354 100644
--- a/ios/MullvadVPN/REST/RESTProxy.swift
+++ b/ios/MullvadVPN/REST/RESTProxy.swift
@@ -32,8 +32,7 @@ extension REST {
configuration: ConfigurationType,
requestFactory: REST.RequestFactory,
responseDecoder: JSONDecoder
- )
- {
+ ) {
dispatchQueue = DispatchQueue(label: "REST.\(name).dispatchQueue")
operationQueue.name = "REST.\(name).operationQueue"
@@ -48,8 +47,7 @@ extension REST {
requestHandler: REST.AnyRequestHandler,
responseHandler: REST.AnyResponseHandler<Success>,
completionHandler: @escaping NetworkOperation<Success>.CompletionHandler
- ) -> Cancellable
- {
+ ) -> Cancellable {
let operation = NetworkOperation(
name: getTaskIdentifier(name: name),
dispatchQueue: dispatchQueue,
diff --git a/ios/MullvadVPN/REST/RESTRequestFactory.swift b/ios/MullvadVPN/REST/RESTRequestFactory.swift
index 2046f26daa..15bccb1930 100644
--- a/ios/MullvadVPN/REST/RESTRequestFactory.swift
+++ b/ios/MullvadVPN/REST/RESTRequestFactory.swift
@@ -15,7 +15,10 @@ extension REST {
let networkTimeout: TimeInterval
let bodyEncoder: JSONEncoder
- class func withDefaultAPICredentials(pathPrefix: String, bodyEncoder: JSONEncoder) -> RequestFactory {
+ class func withDefaultAPICredentials(
+ pathPrefix: String,
+ bodyEncoder: JSONEncoder
+ ) -> RequestFactory {
return RequestFactory(
hostname: ApplicationConfiguration.defaultAPIHostname,
pathPrefix: pathPrefix,
@@ -29,15 +32,18 @@ extension REST {
pathPrefix: String,
networkTimeout: TimeInterval,
bodyEncoder: JSONEncoder
- )
- {
+ ) {
self.hostname = hostname
self.pathPrefix = pathPrefix
self.networkTimeout = networkTimeout
self.bodyEncoder = bodyEncoder
}
- func createRequest(endpoint: AnyIPEndpoint, method: HTTPMethod, pathTemplate: URLPathTemplate) throws -> REST.Request {
+ func createRequest(
+ endpoint: AnyIPEndpoint,
+ method: HTTPMethod,
+ pathTemplate: URLPathTemplate
+ ) throws -> REST.Request {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.path = pathPrefix
@@ -108,10 +114,10 @@ extension REST {
mutating func setAuthorization(_ authorization: REST.Authorization) {
let value: String
switch authorization {
- case .accountNumber(let accountNumber):
+ case let .accountNumber(accountNumber):
value = "Token \(accountNumber)"
- case .accessToken(let accessToken):
+ case let .accessToken(accessToken):
value = "Bearer \(accessToken)"
}
@@ -138,7 +144,7 @@ extension REST {
var errorDescription: String? {
switch self {
- case .noReplacement(let placeholder):
+ case let .noReplacement(placeholder):
return "Replacement is not provided for \(placeholder)."
case .percentEncoding:
@@ -154,7 +160,7 @@ extension REST {
let slashCharset = CharacterSet(charactersIn: "/")
components = value.split(separator: "/").map { subpath -> Component in
- if subpath.hasPrefix("{") && subpath.hasSuffix("}") {
+ if subpath.hasPrefix("{"), subpath.hasSuffix("}") {
let name = String(subpath.dropFirst().dropLast())
return .placeholder(name)
@@ -193,9 +199,9 @@ extension REST {
combinedString += "/"
switch component {
- case .literal(let string):
+ case let .literal(string):
combinedString += string
- case .placeholder(let name):
+ case let .placeholder(name):
combinedString += "{\(name)}"
}
}
@@ -210,10 +216,10 @@ extension REST {
combinedPath += "/"
switch component {
- case .literal(let string):
+ case let .literal(string):
combinedPath += string
- case .placeholder(let name):
+ case let .placeholder(name):
if let string = replacements[name] {
combinedPath += string
} else {
@@ -229,5 +235,4 @@ extension REST {
return URLPathTemplate(components: lhs.components + rhs.components)
}
}
-
}
diff --git a/ios/MullvadVPN/REST/RESTResponseHandler.swift b/ios/MullvadVPN/REST/RESTResponseHandler.swift
index 1ec56541fa..a1262a2d5c 100644
--- a/ios/MullvadVPN/REST/RESTResponseHandler.swift
+++ b/ios/MullvadVPN/REST/RESTResponseHandler.swift
@@ -11,7 +11,8 @@ import Foundation
protocol RESTResponseHandler {
associatedtype Success
- func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST.ResponseHandlerResult<Success>
+ func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST
+ .ResponseHandlerResult<Success>
}
extension REST {
@@ -37,7 +38,9 @@ extension REST {
handlerBlock = block
}
- func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST.ResponseHandlerResult<Success> {
+ func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST
+ .ResponseHandlerResult<Success>
+ {
return handlerBlock(response, data)
}
}
diff --git a/ios/MullvadVPN/REST/SSLPinningURLSessionDelegate.swift b/ios/MullvadVPN/REST/SSLPinningURLSessionDelegate.swift
index 50b0176288..e872d69937 100644
--- a/ios/MullvadVPN/REST/SSLPinningURLSessionDelegate.swift
+++ b/ios/MullvadVPN/REST/SSLPinningURLSessionDelegate.swift
@@ -7,11 +7,10 @@
//
import Foundation
-import Security
import Logging
+import Security
class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
-
private let sslHostname: String
private let trustedRootCertificates: [SecCertificate]
@@ -24,10 +23,15 @@ class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
// MARK: - URLSessionDelegate
- func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ func urlSession(
+ _ session: URLSession,
+ didReceive challenge: URLAuthenticationChallenge,
+ completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
+ ) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
let serverTrust = challenge.protectionSpace.serverTrust,
- verifyServerTrust(serverTrust) {
+ verifyServerTrust(serverTrust)
+ {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.rejectProtectionSpace, nil)
@@ -43,21 +47,27 @@ class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
let sslPolicy = SecPolicyCreateSSL(true, sslHostname as CFString)
secResult = SecTrustSetPolicies(serverTrust, sslPolicy)
guard secResult == errSecSuccess else {
- logger.error("SecTrustSetPolicies failure: \(self.formatErrorMessage(code: secResult))")
+ logger.error("SecTrustSetPolicies failure: \(formatErrorMessage(code: secResult))")
return false
}
// Set trusted root certificates
secResult = SecTrustSetAnchorCertificates(serverTrust, trustedRootCertificates as CFArray)
guard secResult == errSecSuccess else {
- logger.error("SecTrustSetAnchorCertificates failure: \(self.formatErrorMessage(code: secResult))")
+ logger
+ .error(
+ "SecTrustSetAnchorCertificates failure: \(formatErrorMessage(code: secResult))"
+ )
return false
}
// Tell security framework to only trust the provided root certificates
secResult = SecTrustSetAnchorCertificatesOnly(serverTrust, true)
guard secResult == errSecSuccess else {
- logger.error("SecTrustSetAnchorCertificatesOnly failure: \(self.formatErrorMessage(code: secResult))")
+ logger
+ .error(
+ "SecTrustSetAnchorCertificatesOnly failure: \(formatErrorMessage(code: secResult))"
+ )
return false
}
@@ -65,7 +75,10 @@ class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
if SecTrustEvaluateWithError(serverTrust, &error) {
return true
} else {
- logger.error("SecTrustEvaluateWithError failure: \(error?.localizedDescription ?? "<nil>")")
+ logger
+ .error(
+ "SecTrustEvaluateWithError failure: \(error?.localizedDescription ?? "<nil>")"
+ )
return false
}
}
diff --git a/ios/MullvadVPN/RelayCache/CachedRelays.swift b/ios/MullvadVPN/RelayCache/CachedRelays.swift
index a4cbcc93e5..9675f60c5c 100644
--- a/ios/MullvadVPN/RelayCache/CachedRelays.swift
+++ b/ios/MullvadVPN/RelayCache/CachedRelays.swift
@@ -9,7 +9,6 @@
import Foundation
extension RelayCache {
-
/// A struct that represents the relay cache on disk
struct CachedRelays: Codable {
/// E-tag returned by server
@@ -21,5 +20,4 @@ extension RelayCache {
/// The date when this cache was last updated
var updatedAt: Date
}
-
}
diff --git a/ios/MullvadVPN/RelayCache/RelayCacheIO.swift b/ios/MullvadVPN/RelayCache/RelayCacheIO.swift
index 6a2a4deb13..fe23e02186 100644
--- a/ios/MullvadVPN/RelayCache/RelayCacheIO.swift
+++ b/ios/MullvadVPN/RelayCache/RelayCacheIO.swift
@@ -86,7 +86,7 @@ extension RelayCache.IO {
/// Safely write the cache file on disk using file coordinator.
static func write(cacheFileURL: URL, record: RelayCache.CachedRelays) throws {
- var result: Result<(), Error>?
+ var result: Result<Void, Error>?
let fileCoordinator = NSFileCoordinator(filePresenter: nil)
let accessor = { (fileURLForWriting: URL) in
diff --git a/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift b/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift
index 702e5b9273..ec56e2b5bb 100644
--- a/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift
+++ b/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift
@@ -11,7 +11,6 @@ import Logging
import UIKit
extension RelayCache {
-
/// Type describing the result of an attempt to fetch the new relay list from server.
enum FetchResult: CustomStringConvertible {
/// Request to update relays was throttled.
@@ -81,7 +80,11 @@ extension RelayCache {
/// A shared instance of `RelayCache`
static let shared: RelayCache.Tracker = {
- let cacheFileURL = RelayCache.IO.defaultCacheFileURL(forSecurityApplicationGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier)!
+ let cacheFileURL = RelayCache.IO
+ .defaultCacheFileURL(
+ forSecurityApplicationGroupIdentifier: ApplicationConfiguration
+ .securityGroupIdentifier
+ )!
let prebundledRelaysFileURL = RelayCache.IO.preBundledRelaysFileURL!
return Tracker(
@@ -142,8 +145,7 @@ extension RelayCache {
completionHandler: (
(OperationCompletion<RelayCache.FetchResult, Error>) -> Void
)? = nil
- ) -> Cancellable
- {
+ ) -> Cancellable {
let operation = ResultBlockOperation<RelayCache.FetchResult, Error>(
dispatchQueue: nil
) { operation in
@@ -224,11 +226,10 @@ extension RelayCache {
private func handleResponse(
completion: OperationCompletion<REST.ServerRelaysCacheResponse, REST.Error>
- ) -> OperationCompletion<FetchResult, Error>
- {
+ ) -> OperationCompletion<FetchResult, Error> {
let mappedCompletion = completion.tryMap { response -> FetchResult in
switch response {
- case .newContent(let etag, let relays):
+ case let .newContent(etag, relays):
try self.storeResponse(etag: etag, relays: relays)
return .newContent
@@ -275,7 +276,6 @@ extension RelayCache {
}
}
-
private func scheduleRepeatingTimer(startTime: DispatchWallTime) {
let timerSource = DispatchSource.makeTimerSource()
timerSource.setEventHandler { [weak self] in
@@ -291,5 +291,4 @@ extension RelayCache {
self.timerSource = timerSource
}
}
-
}
diff --git a/ios/MullvadVPN/RelayConstraints.swift b/ios/MullvadVPN/RelayConstraints.swift
index 7bedd611a1..e6637f4fd3 100644
--- a/ios/MullvadVPN/RelayConstraints.swift
+++ b/ios/MullvadVPN/RelayConstraints.swift
@@ -15,7 +15,7 @@ enum RelayConstraint<T>: Codable, Equatable where T: Codable & Equatable {
case only(T)
var value: T? {
- if case .only(let value) = self {
+ if case let .only(value) = self {
return value
} else {
return nil
@@ -45,7 +45,7 @@ enum RelayConstraint<T>: Codable, Equatable where T: Codable & Equatable {
switch self {
case .any:
try container.encode(kRelayConstraintAnyRepr)
- case .only(let inner):
+ case let .only(inner):
try container.encode(OnlyRepr(only: inner))
}
}
@@ -57,7 +57,7 @@ extension RelayConstraint: CustomDebugStringConvertible {
switch self {
case .any:
output += "any"
- case .only(let value):
+ case let .only(value):
output += "only(\(String(reflecting: value)))"
}
return output
@@ -99,7 +99,8 @@ enum RelayLocation: Codable, Hashable {
default:
throw DecodingError.dataCorruptedError(
in: container,
- debugDescription: "Invalid enum representation")
+ debugDescription: "Invalid enum representation"
+ )
}
}
@@ -107,13 +108,13 @@ enum RelayLocation: Codable, Hashable {
var container = encoder.singleValueContainer()
switch self {
- case .country(let code):
+ case let .country(code):
try container.encode([code])
- case .city(let countryCode, let cityCode):
+ case let .city(countryCode, cityCode):
try container.encode([countryCode, cityCode])
- case .hostname(let countryCode, let cityCode, let hostname):
+ case let .hostname(countryCode, cityCode, hostname):
try container.encode([countryCode, cityCode, hostname])
}
}
@@ -121,17 +122,16 @@ enum RelayLocation: Codable, Hashable {
/// A list of `RelayLocation` items preceding the given one in the relay tree
var ascendants: [RelayLocation] {
switch self {
- case .hostname(let country, let city, _):
+ case let .hostname(country, city, _):
return [.country(country), .city(country, city)]
- case .city(let country, _):
+ case let .city(country, _):
return [.country(country)]
case .country:
return []
}
}
-
}
extension RelayLocation: CustomDebugStringConvertible {
@@ -139,13 +139,13 @@ extension RelayLocation: CustomDebugStringConvertible {
var output = "RelayLocation."
switch self {
- case .country(let country):
+ case let .country(country):
output += "country(\(String(reflecting: country)))"
- case .city(let country, let city):
+ case let .city(country, city):
output += "city(\(String(reflecting: country)), \(String(reflecting: city)))"
- case .hostname(let country, let city, let host):
+ case let .hostname(country, city, host):
output += "hostname(\(String(reflecting: country)), " +
"\(String(reflecting: city)), " +
"\(String(reflecting: host)))"
@@ -156,11 +156,11 @@ extension RelayLocation: CustomDebugStringConvertible {
var stringRepresentation: String {
switch self {
- case .country(let country):
+ case let .country(country):
return country
- case .city(let country, let city):
+ case let .city(country, city):
return "\(country)-\(city)"
- case .hostname(let country, let city, let host):
+ case let .hostname(country, city, host):
return "\(country)-\(city)-\(host)"
}
}
diff --git a/ios/MullvadVPN/RelaySelector.swift b/ios/MullvadVPN/RelaySelector.swift
index c29c8ccef5..2b2a269c41 100644
--- a/ios/MullvadVPN/RelaySelector.swift
+++ b/ios/MullvadVPN/RelaySelector.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import Network
import Logging
+import Network
struct RelaySelectorResult: Codable {
var endpoint: MullvadEndpoint
@@ -41,12 +41,15 @@ struct NoRelaysSatisfyingConstraintsError: LocalizedError {
enum RelaySelector {}
extension RelaySelector {
-
- static func evaluate(relays: REST.ServerRelaysResponse, constraints: RelayConstraints) throws -> RelaySelectorResult {
+ static func evaluate(
+ relays: REST.ServerRelaysResponse,
+ constraints: RelayConstraints
+ ) throws -> RelaySelectorResult {
let filteredRelays = applyConstraints(constraints, relays: Self.parseRelaysResponse(relays))
guard let relayWithLocation = pickRandomRelay(relays: filteredRelays),
- let port = pickRandomPort(rawPortRanges: relays.wireguard.portRanges) else {
+ let port = pickRandomPort(rawPortRanges: relays.wireguard.portRanges)
+ else {
throw NoRelaysSatisfyingConstraintsError()
}
@@ -69,28 +72,31 @@ extension RelaySelector {
}
/// Produce a list of `RelayWithLocation` items satisfying the given constraints
- private static func applyConstraints(_ constraints: RelayConstraints, relays: [RelayWithLocation]) -> [RelayWithLocation] {
- return relays.filter { (relayWithLocation) -> Bool in
+ private static func applyConstraints(
+ _ constraints: RelayConstraints,
+ relays: [RelayWithLocation]
+ ) -> [RelayWithLocation] {
+ return relays.filter { relayWithLocation -> Bool in
switch constraints.location {
case .any:
return true
- case .only(let relayConstraint):
+ case let .only(relayConstraint):
switch relayConstraint {
- case .country(let countryCode):
+ case let .country(countryCode):
return relayWithLocation.location.countryCode == countryCode &&
relayWithLocation.relay.includeInCountry
- case .city(let countryCode, let cityCode):
+ case let .city(countryCode, cityCode):
return relayWithLocation.location.countryCode == countryCode &&
relayWithLocation.location.cityCode == cityCode
- case .hostname(let countryCode, let cityCode, let hostname):
+ case let .hostname(countryCode, cityCode, hostname):
return relayWithLocation.location.countryCode == countryCode &&
relayWithLocation.location.cityCode == cityCode &&
relayWithLocation.relay.hostname == hostname
}
}
- }.filter { (relayWithLocation) -> Bool in
+ }.filter { relayWithLocation -> Bool in
return relayWithLocation.relay.active
}
}
@@ -107,10 +113,11 @@ extension RelaySelector {
// Pick a random number in the range 1 - totalWeight. This choses the relay with a
// non-zero weight.
- var i = (1...totalWeight).randomElement()!
+ var i = (1 ... totalWeight).randomElement()!
- let randomRelay = relays.first { (relayWithLocation) -> Bool in
- let (result, isOverflow) = i.subtractingReportingOverflow(relayWithLocation.relay.weight)
+ let randomRelay = relays.first { relayWithLocation -> Bool in
+ let (result, isOverflow) = i
+ .subtractingReportingOverflow(relayWithLocation.relay.weight)
i = isOverflow ? 0 : result
@@ -128,7 +135,7 @@ extension RelaySelector {
return partialResult + closedRange.count
}
- guard var portIndex = (0..<portAmount).randomElement() else {
+ guard var portIndex = (0 ..< portAmount).randomElement() else {
return nil
}
@@ -154,15 +161,18 @@ extension RelaySelector {
let endPort = inputRange[1]
if startPort <= endPort {
- return (startPort...endPort)
+ return (startPort ... endPort)
} else {
return nil
}
}
}
- private static func parseRelaysResponse(_ response: REST.ServerRelaysResponse) -> [RelayWithLocation] {
- return response.wireguard.relays.compactMap { (serverRelay) -> RelayWithLocation? in
+ private static func parseRelaysResponse(
+ _ response: REST
+ .ServerRelaysResponse
+ ) -> [RelayWithLocation] {
+ return response.wireguard.relays.compactMap { serverRelay -> RelayWithLocation? in
guard let serverLocation = response.locations[serverRelay.location] else { return nil }
let locationComponents = serverRelay.location.split(separator: "-")
@@ -180,5 +190,4 @@ extension RelaySelector {
return RelayWithLocation(relay: serverRelay, location: location)
}
}
-
}
diff --git a/ios/MullvadVPN/Result+Extensions.swift b/ios/MullvadVPN/Result+Extensions.swift
index 9a2245d673..0ea447752e 100644
--- a/ios/MullvadVPN/Result+Extensions.swift
+++ b/ios/MullvadVPN/Result+Extensions.swift
@@ -11,7 +11,7 @@ import Foundation
extension Result {
var value: Success? {
switch self {
- case .success(let value):
+ case let .success(value):
return value
case .failure:
return nil
@@ -22,16 +22,16 @@ extension Result {
switch self {
case .success:
return nil
- case .failure(let error):
+ case let .failure(error):
return error
}
}
}
extension Result {
- func flattenValue<T>() -> T? where Success == Optional<T> {
+ func flattenValue<T>() -> T? where Success == T? {
switch self {
- case .success(let optional):
+ case let .success(optional):
return optional.flatMap { $0 }
case .failure:
return nil
diff --git a/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift b/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift
index 6cebcaaa75..e9bcf01c62 100644
--- a/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift
+++ b/ios/MullvadVPN/Result+UIBackgroundFetchResult.swift
@@ -11,7 +11,7 @@ import UIKit
extension OperationCompletion {
func backgroundFetchResult(_ hasNewData: (Success) -> Bool) -> UIBackgroundFetchResult {
switch self {
- case .success(let value):
+ case let .success(value):
return hasNewData(value) ? .newData : .noData
case .cancelled:
return .noData
@@ -31,7 +31,7 @@ extension UIBackgroundFetchResult: CustomStringConvertible {
case .failed:
return "failed"
@unknown default:
- return "unknown (rawValue: \(self.rawValue)"
+ return "unknown (rawValue: \(rawValue)"
}
}
diff --git a/ios/MullvadVPN/RevokedDeviceViewController.swift b/ios/MullvadVPN/RevokedDeviceViewController.swift
index 117ad69e91..f4c02367ca 100644
--- a/ios/MullvadVPN/RevokedDeviceViewController.swift
+++ b/ios/MullvadVPN/RevokedDeviceViewController.swift
@@ -13,9 +13,8 @@ protocol RevokedDeviceViewControllerDelegate: AnyObject {
}
class RevokedDeviceViewController: UIViewController, RootContainment, TunnelObserver {
-
private lazy var imageView: StatusImageView = {
- let statusImageView = StatusImageView(style: .failure)
+ let statusImageView = StatusImageView(style: .failure)
statusImageView.translatesAutoresizingMaskIntoConstraints = false
return statusImageView
}()
@@ -147,7 +146,7 @@ class RevokedDeviceViewController: UIViewController, RootContainment, TunnelObse
logoutButton.topAnchor.constraint(greaterThanOrEqualTo: footerLabel.bottomAnchor),
logoutButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
logoutButton.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
- logoutButton.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor)
+ logoutButton.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor),
])
TunnelManager.shared.addObserver(self)
@@ -180,12 +179,14 @@ class RevokedDeviceViewController: UIViewController, RootContainment, TunnelObse
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
func tunnelManager(_ manager: TunnelManager, didFailWithError error: Error) {
// no-op
}
-
}
diff --git a/ios/MullvadVPN/RootContainerViewController.swift b/ios/MullvadVPN/RootContainerViewController.swift
index 35d48ef157..573f4c5c7f 100644
--- a/ios/MullvadVPN/RootContainerViewController.swift
+++ b/ios/MullvadVPN/RootContainerViewController.swift
@@ -36,26 +36,29 @@ struct HeaderBarPresentation {
/// A protocol that defines the relationship between the root container and its child controllers
protocol RootContainment {
-
/// Return the preferred header bar style
var preferredHeaderBarPresentation: HeaderBarPresentation { get }
/// Return true if the view controller prefers header bar hidden
var prefersHeaderBarHidden: Bool { get }
-
}
protocol RootContainerViewControllerDelegate: AnyObject {
- func rootContainerViewControllerShouldShowSettings(_ controller: RootContainerViewController, navigateTo route: SettingsNavigationRoute?, animated: Bool)
+ func rootContainerViewControllerShouldShowSettings(
+ _ controller: RootContainerViewController,
+ navigateTo route: SettingsNavigationRoute?,
+ animated: Bool
+ )
- func rootContainerViewSupportedInterfaceOrientations(_ controller: RootContainerViewController) -> UIInterfaceOrientationMask
+ func rootContainerViewSupportedInterfaceOrientations(_ controller: RootContainerViewController)
+ -> UIInterfaceOrientationMask
- func rootContainerViewAccessibilityPerformMagicTap(_ controller: RootContainerViewController) -> Bool
+ func rootContainerViewAccessibilityPerformMagicTap(_ controller: RootContainerViewController)
+ -> Bool
}
/// A root container view controller
class RootContainerViewController: UIViewController {
-
typealias CompletionHandler = () -> Void
private let headerBarView = HeaderBarView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
@@ -91,7 +94,8 @@ class RootContainerViewController: UIViewController {
}
override var disablesAutomaticKeyboardDismissal: Bool {
- return topViewController?.disablesAutomaticKeyboardDismissal ?? super.disablesAutomaticKeyboardDismissal
+ return topViewController?.disablesAutomaticKeyboardDismissal ?? super
+ .disablesAutomaticKeyboardDismissal
}
// MARK: - View lifecycle
@@ -165,10 +169,11 @@ class RootContainerViewController: UIViewController {
// MARK: - Public
- func setViewControllers(_ newViewControllers: [UIViewController],
- animated: Bool,
- completion: CompletionHandler? = nil)
- {
+ func setViewControllers(
+ _ newViewControllers: [UIViewController],
+ animated: Bool,
+ completion: CompletionHandler? = nil
+ ) {
// Fetch the initial orientation mask
if interfaceOrientationMask == nil {
updateInterfaceOrientation(attemptRotateToDeviceOrientation: false)
@@ -182,11 +187,20 @@ class RootContainerViewController: UIViewController {
)
}
- func pushViewController(_ viewController: UIViewController, animated: Bool, completion: CompletionHandler? = nil) {
- var newViewControllers = viewControllers.filter({ $0 != viewController })
+ func pushViewController(
+ _ viewController: UIViewController,
+ animated: Bool,
+ completion: CompletionHandler? = nil
+ ) {
+ var newViewControllers = viewControllers.filter { $0 != viewController }
newViewControllers.append(viewController)
- setViewControllersInternal(newViewControllers, isUnwinding: false, animated: animated, completion: completion)
+ setViewControllersInternal(
+ newViewControllers,
+ isUnwinding: false,
+ animated: animated,
+ completion: completion
+ )
}
func popViewController(animated: Bool, completion: CompletionHandler? = nil) {
@@ -195,12 +209,22 @@ class RootContainerViewController: UIViewController {
var newViewControllers = viewControllers
newViewControllers.removeLast()
- setViewControllersInternal(newViewControllers, isUnwinding: true, animated: animated, completion: completion)
+ setViewControllersInternal(
+ newViewControllers,
+ isUnwinding: true,
+ animated: animated,
+ completion: completion
+ )
}
func popToRootViewController(animated: Bool, completion: CompletionHandler? = nil) {
- if let rootController = self.viewControllers.first, self.viewControllers.count > 1 {
- setViewControllersInternal([rootController], isUnwinding: true, animated: animated, completion: completion)
+ if let rootController = viewControllers.first, viewControllers.count > 1 {
+ setViewControllersInternal(
+ [rootController],
+ isUnwinding: true,
+ animated: animated,
+ completion: completion
+ )
}
}
@@ -215,7 +239,11 @@ class RootContainerViewController: UIViewController {
/// Request to display settings controller
func showSettings(navigateTo route: SettingsNavigationRoute? = nil, animated: Bool) {
- delegate?.rootContainerViewControllerShouldShowSettings(self, navigateTo: route, animated: animated)
+ delegate?.rootContainerViewControllerShouldShowSettings(
+ self,
+ navigateTo: route,
+ animated: animated
+ )
}
/// Enable or disable the settings bar button displayed in the header bar
@@ -235,7 +263,11 @@ class RootContainerViewController: UIViewController {
} else {
settingsButton = HeaderBarView.makeSettingsButton()
settingsButton.isEnabled = headerBarView.settingsButton.isEnabled
- settingsButton.addTarget(self, action: #selector(handleSettingsButtonTap), for: .touchUpInside)
+ settingsButton.addTarget(
+ self,
+ action: #selector(handleSettingsButtonTap),
+ for: .touchUpInside
+ )
presentationContainerSettingsButton = settingsButton
}
@@ -246,8 +278,10 @@ class RootContainerViewController: UIViewController {
presentationContainer.addSubview(settingsButton)
NSLayoutConstraint.activate([
- settingsButton.centerXAnchor.constraint(equalTo: headerBarView.settingsButton.centerXAnchor),
- settingsButton.centerYAnchor.constraint(equalTo: headerBarView.settingsButton.centerYAnchor),
+ settingsButton.centerXAnchor
+ .constraint(equalTo: headerBarView.settingsButton.centerXAnchor),
+ settingsButton.centerYAnchor
+ .constraint(equalTo: headerBarView.settingsButton.centerYAnchor),
])
}
@@ -269,7 +303,8 @@ class RootContainerViewController: UIViewController {
// MARK: - Accessibility
override func accessibilityPerformMagicTap() -> Bool {
- return delegate?.rootContainerViewAccessibilityPerformMagicTap(self) ?? super.accessibilityPerformMagicTap()
+ return delegate?.rootContainerViewAccessibilityPerformMagicTap(self) ?? super
+ .accessibilityPerformMagicTap()
}
// MARK: - Private
@@ -279,7 +314,7 @@ class RootContainerViewController: UIViewController {
transitionContainer.topAnchor.constraint(equalTo: view.topAnchor),
transitionContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
transitionContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- transitionContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ transitionContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
]
transitionContainer.translatesAutoresizingMaskIntoConstraints = false
@@ -292,7 +327,7 @@ class RootContainerViewController: UIViewController {
let constraints = [
headerBarView.topAnchor.constraint(equalTo: view.topAnchor),
headerBarView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- headerBarView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
+ headerBarView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
]
headerBarView.translatesAutoresizingMaskIntoConstraints = false
@@ -300,7 +335,11 @@ class RootContainerViewController: UIViewController {
// Prevent automatic layout margins adjustment as we manually control them.
headerBarView.insetsLayoutMarginsFromSafeArea = false
- headerBarView.settingsButton.addTarget(self, action: #selector(handleSettingsButtonTap), for: .touchUpInside)
+ headerBarView.settingsButton.addTarget(
+ self,
+ action: #selector(handleSettingsButtonTap),
+ for: .touchUpInside
+ )
view.addSubview(headerBarView)
@@ -311,7 +350,12 @@ class RootContainerViewController: UIViewController {
showSettings(animated: true)
}
- private func setViewControllersInternal(_ newViewControllers: [UIViewController], isUnwinding: Bool, animated: Bool, completion: CompletionHandler? = nil) {
+ private func setViewControllersInternal(
+ _ newViewControllers: [UIViewController],
+ isUnwinding: Bool,
+ animated: Bool,
+ completion: CompletionHandler? = nil
+ ) {
// Dot not handle appearance events when the container itself is not visible
let shouldHandleAppearanceEvents = view.window != nil
@@ -348,7 +392,9 @@ class RootContainerViewController: UIViewController {
self.endChildControllerTransition(sourceViewController)
}
- if let targetViewController = targetViewController, sourceViewController != targetViewController {
+ if let targetViewController = targetViewController,
+ sourceViewController != targetViewController
+ {
self.endChildControllerTransition(targetViewController)
}
}
@@ -394,10 +440,20 @@ class RootContainerViewController: UIViewController {
// Begin appearance transition
if shouldHandleAppearanceEvents {
if let sourceViewController = sourceViewController {
- beginChildControllerTransition(sourceViewController, isAppearing: false, animated: shouldAnimate)
+ beginChildControllerTransition(
+ sourceViewController,
+ isAppearing: false,
+ animated: shouldAnimate
+ )
}
- if let targetViewController = targetViewController, sourceViewController != targetViewController {
- beginChildControllerTransition(targetViewController, isAppearing: true, animated: shouldAnimate)
+ if let targetViewController = targetViewController,
+ sourceViewController != targetViewController
+ {
+ beginChildControllerTransition(
+ targetViewController,
+ isAppearing: true,
+ animated: shouldAnimate
+ )
}
setNeedsStatusBarAppearanceUpdate()
}
@@ -413,12 +469,12 @@ class RootContainerViewController: UIViewController {
transition.type = .push
// Pick the animation movement direction
- let sourceIndex = sourceViewController.flatMap({ newViewControllers.firstIndex(of: $0) })
- let targetIndex = targetViewController.flatMap({ newViewControllers.firstIndex(of: $0) })
+ let sourceIndex = sourceViewController.flatMap { newViewControllers.firstIndex(of: $0) }
+ let targetIndex = targetViewController.flatMap { newViewControllers.firstIndex(of: $0) }
switch (sourceIndex, targetIndex) {
- case (.some(let lhs), .some(let rhs)):
- transition.subtype = lhs > rhs ? .fromLeft : .fromRight
+ case let (.some(lhs), .some(rhs)):
+ transition.subtype = lhs > rhs ? .fromLeft : .fromRight
case (.none, .some):
transition.subtype = isUnwinding ? .fromLeft : .fromRight
default:
@@ -511,7 +567,8 @@ class RootContainerViewController: UIViewController {
}
private func updateInterfaceOrientation(attemptRotateToDeviceOrientation: Bool) {
- let newSupportedOrientations = delegate?.rootContainerViewSupportedInterfaceOrientations(self)
+ let newSupportedOrientations = delegate?
+ .rootContainerViewSupportedInterfaceOrientations(self)
if interfaceOrientationMask != newSupportedOrientations {
interfaceOrientationMask = newSupportedOrientations
@@ -523,7 +580,11 @@ class RootContainerViewController: UIViewController {
}
}
- private func beginChildControllerTransition(_ controller: UIViewController, isAppearing: Bool, animated: Bool) {
+ private func beginChildControllerTransition(
+ _ controller: UIViewController,
+ isAppearing: Bool,
+ animated: Bool
+ ) {
if appearingController != controller, isAppearing {
appearingController = controller
controller.beginAppearanceTransition(isAppearing, animated: animated)
@@ -554,12 +615,10 @@ class RootContainerViewController: UIViewController {
// Tell accessibility that the significant part of screen was changed.
UIAccessibility.post(notification: .screenChanged, argument: nil)
}
-
}
/// A UIViewController extension that gives view controllers an access to root container
extension UIViewController {
-
var rootContainerController: RootContainerViewController? {
var current: UIViewController? = self
let iterator = AnyIterator { () -> UIViewController? in
@@ -577,5 +636,4 @@ extension UIViewController {
func setNeedsHeaderBarHiddenAppearanceUpdate() {
rootContainerController?.updateHeaderBarHiddenAppearance()
}
-
}
diff --git a/ios/MullvadVPN/SKProduct+Formatting.swift b/ios/MullvadVPN/SKProduct+Formatting.swift
index 19063622bc..b5bf461ef6 100644
--- a/ios/MullvadVPN/SKProduct+Formatting.swift
+++ b/ios/MullvadVPN/SKProduct+Formatting.swift
@@ -10,7 +10,6 @@ import Foundation
import StoreKit
extension SKProduct {
-
var localizedPrice: String? {
let formatter = NumberFormatter()
formatter.locale = priceLocale
@@ -18,5 +17,4 @@ extension SKProduct {
return formatter.string(from: price)
}
-
}
diff --git a/ios/MullvadVPN/SceneDelegate.swift b/ios/MullvadVPN/SceneDelegate.swift
index 5fe4dcbc52..003672284d 100644
--- a/ios/MullvadVPN/SceneDelegate.swift
+++ b/ios/MullvadVPN/SceneDelegate.swift
@@ -6,8 +6,8 @@
// Copyright © 2022 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
class SceneDelegate: UIResponder {
private let logger = Logger(label: "SceneDelegate")
@@ -177,7 +177,11 @@ extension SceneDelegate: UIWindowSceneDelegate {
// MARK: - RootContainerViewControllerDelegate
extension SceneDelegate: RootContainerViewControllerDelegate {
- func rootContainerViewControllerShouldShowSettings(_ controller: RootContainerViewController, navigateTo route: SettingsNavigationRoute?, animated: Bool) {
+ func rootContainerViewControllerShouldShowSettings(
+ _ controller: RootContainerViewController,
+ navigateTo route: SettingsNavigationRoute?,
+ animated: Bool
+ ) {
// Check if settings controller is already presented.
if let settingsNavController = settingsNavController {
if let route = route {
@@ -197,11 +201,13 @@ extension SceneDelegate: RootContainerViewControllerDelegate {
}
// Save the reference for later.
- self.settingsNavController = navController
+ settingsNavController = navController
}
}
- func rootContainerViewSupportedInterfaceOrientations(_ controller: RootContainerViewController) -> UIInterfaceOrientationMask {
+ func rootContainerViewSupportedInterfaceOrientations(_ controller: RootContainerViewController)
+ -> UIInterfaceOrientationMask
+ {
switch UIDevice.current.userInterfaceIdiom {
case .pad:
return [.landscape, .portrait]
@@ -212,7 +218,9 @@ extension SceneDelegate: RootContainerViewControllerDelegate {
}
}
- func rootContainerViewAccessibilityPerformMagicTap(_ controller: RootContainerViewController) -> Bool {
+ func rootContainerViewAccessibilityPerformMagicTap(_ controller: RootContainerViewController)
+ -> Bool
+ {
guard TunnelManager.shared.deviceState.isLoggedIn else { return false }
switch TunnelManager.shared.tunnelStatus.state {
@@ -228,7 +236,6 @@ extension SceneDelegate: RootContainerViewControllerDelegate {
}
extension SceneDelegate {
-
private func setupPadUI() {
let tunnelManager = TunnelManager.shared
let selectLocationController = makeSelectLocationController()
@@ -237,12 +244,13 @@ extension SceneDelegate {
let splitViewController = CustomSplitViewController()
splitViewController.delegate = self
splitViewController.minimumPrimaryColumnWidth = UIMetrics.minimumSplitViewSidebarWidth
- splitViewController.preferredPrimaryColumnWidthFraction = UIMetrics.maximumSplitViewSidebarWidthFraction
+ splitViewController.preferredPrimaryColumnWidthFraction = UIMetrics
+ .maximumSplitViewSidebarWidthFraction
splitViewController.primaryEdge = .trailing
splitViewController.dividerColor = UIColor.MainSplitView.dividerColor
splitViewController.viewControllers = [selectLocationController, connectController]
- self.selectLocationViewController = selectLocationController
+ selectLocationViewController = selectLocationController
self.splitViewController = splitViewController
self.connectController = connectController
@@ -264,7 +272,10 @@ extension SceneDelegate {
// Dismiss modal root container if needed before proceeding.
if self.isModalRootPresented {
- self.modalRootContainer.dismiss(animated: animated, completion: didDismissModalRoot)
+ self.modalRootContainer.dismiss(
+ animated: animated,
+ completion: didDismissModalRoot
+ )
} else {
didDismissModalRoot()
}
@@ -291,7 +302,7 @@ extension SceneDelegate {
if TermsOfService.isAgreed {
showNextController(false)
} else {
- let termsOfServiceController = self.makeTermsOfServiceController { _ in
+ let termsOfServiceController = makeTermsOfServiceController { _ in
showNextController(true)
}
@@ -346,7 +357,7 @@ extension SceneDelegate {
if TermsOfService.isAgreed {
showNextController(false)
} else {
- let termsOfServiceController = self.makeTermsOfServiceController { _ in
+ let termsOfServiceController = makeTermsOfServiceController { _ in
showNextController(true)
}
@@ -354,7 +365,9 @@ extension SceneDelegate {
}
}
- private func makeSettingsNavigationController(route: SettingsNavigationRoute?) -> SettingsNavigationController {
+ private func makeSettingsNavigationController(route: SettingsNavigationRoute?)
+ -> SettingsNavigationController
+ {
let navController = SettingsNavigationController()
navController.settingsDelegate = self
@@ -400,8 +413,7 @@ extension SceneDelegate {
private func makeTermsOfServiceController(
completion: @escaping (UIViewController) -> Void
- ) -> TermsOfServiceViewController
- {
+ ) -> TermsOfServiceViewController {
let controller = TermsOfServiceViewController()
if UIDevice.current.userInterfaceIdiom == .pad {
@@ -432,7 +444,7 @@ extension SceneDelegate {
}
private func showAccountSettingsControllerIfAccountExpired() {
- guard case .loggedIn(let accountData, _) = TunnelManager.shared.deviceState else {
+ guard case let .loggedIn(accountData, _) = TunnelManager.shared.deviceState else {
return
}
@@ -481,7 +493,6 @@ extension SceneDelegate {
// MARK: - LoginViewControllerDelegate
extension SceneDelegate: LoginViewControllerDelegate {
-
func loginViewController(
_ controller: LoginViewController,
shouldHandleLoginAction action: LoginAction,
@@ -495,11 +506,11 @@ extension SceneDelegate: LoginViewControllerDelegate {
// RootContainer's settings button will be re-enabled in `loginViewControllerDidFinishLogin`
completion(operationCompletion)
- case .failure(let error):
+ case let .failure(error):
// Show device management controller when too many devices detected during log in.
- if case .useExistingAccount(let accountNumber) = action,
- let restError = error as? REST.Error,
- restError.compareErrorCode(.maxDevicesReached)
+ if case let .useExistingAccount(accountNumber) = action,
+ let restError = error as? REST.Error,
+ restError.compareErrorCode(.maxDevicesReached)
{
self.lastLoginAction = action
@@ -508,17 +519,18 @@ extension SceneDelegate: LoginViewControllerDelegate {
)
deviceController.delegate = self
- deviceController.fetchDevices(animateUpdates: false) { [weak self] operationCompletion in
- controller.rootContainerController?.pushViewController(
- deviceController,
- animated: true
- )
+ deviceController
+ .fetchDevices(animateUpdates: false) { [weak self] operationCompletion in
+ controller.rootContainerController?.pushViewController(
+ deviceController,
+ animated: true
+ )
- // Return .cancelled to login controller upon success.
- completion(operationCompletion.flatMap { .cancelled })
+ // Return .cancelled to login controller upon success.
+ completion(operationCompletion.flatMap { .cancelled })
- self?.setEnableSettingsButton(isEnabled: true, from: controller)
- }
+ self?.setEnableSettingsButton(isEnabled: true, from: controller)
+ }
} else {
fallthrough
}
@@ -527,12 +539,11 @@ extension SceneDelegate: LoginViewControllerDelegate {
self.setEnableSettingsButton(isEnabled: true, from: controller)
completion(operationCompletion)
}
-
}
}
func loginViewControllerDidFinishLogin(_ controller: LoginViewController) {
- self.lastLoginAction = nil
+ lastLoginAction = nil
// Move the settings button back into header bar
rootContainer.removeSettingsButtonFromPresentationContainer()
@@ -547,13 +558,13 @@ extension SceneDelegate: LoginViewControllerDelegate {
switch UIDevice.current.userInterfaceIdiom {
case .phone:
- let connectController = self.makeConnectViewController()
+ let connectController = makeConnectViewController()
rootContainer.pushViewController(connectController, animated: true) {
self.showAccountSettingsControllerIfAccountExpired()
}
self.connectController = connectController
case .pad:
- self.showSplitViewMaster(true, animated: true)
+ showSplitViewMaster(true, animated: true)
controller.dismiss(animated: true) {
self.showAccountSettingsControllerIfAccountExpired()
@@ -570,7 +581,6 @@ extension SceneDelegate: LoginViewControllerDelegate {
container.setEnableSettingsButton(isEnabled)
}
}
-
}
// MARK: - DeviceManagementViewControllerDelegate
@@ -582,7 +592,8 @@ extension SceneDelegate: DeviceManagementViewControllerDelegate {
func deviceManagementViewControllerDidFinish(_ controller: DeviceManagementViewController) {
let currentRootContainer = controller.rootContainerController
- let loginViewController = currentRootContainer?.viewControllers.first as? LoginViewController
+ let loginViewController = currentRootContainer?.viewControllers
+ .first as? LoginViewController
currentRootContainer?.popViewController(animated: true) {
if let lastLoginAction = self.lastLoginAction {
@@ -595,25 +606,29 @@ extension SceneDelegate: DeviceManagementViewControllerDelegate {
// MARK: - SettingsNavigationControllerDelegate
extension SceneDelegate: SettingsNavigationControllerDelegate {
-
- func settingsNavigationController(_ controller: SettingsNavigationController, didFinishWithReason reason: SettingsDismissReason) {
+ func settingsNavigationController(
+ _ controller: SettingsNavigationController,
+ didFinishWithReason reason: SettingsDismissReason
+ ) {
if case .userLoggedOut = reason {
showLoginViewAfterLogout(dismissController: controller)
} else {
controller.dismiss(animated: true)
}
}
-
}
// MARK: - ConnectViewControllerDelegate
extension SceneDelegate: ConnectViewControllerDelegate {
-
func connectViewControllerShouldShowSelectLocationPicker(_ controller: ConnectViewController) {
let contentController = makeSelectLocationController()
contentController.navigationItem.largeTitleDisplayMode = .never
- contentController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDismissSelectLocationController(_:)))
+ contentController.navigationItem.rightBarButtonItem = UIBarButtonItem(
+ barButtonSystemItem: .done,
+ target: self,
+ action: #selector(handleDismissSelectLocationController(_:))
+ )
let navController = SelectLocationNavigationController(contentController: contentController)
rootContainer.present(navController, animated: true)
@@ -629,7 +644,10 @@ extension SceneDelegate: ConnectViewControllerDelegate {
// MARK: - NotificationManagerDelegate
extension SceneDelegate: NotificationManagerDelegate {
- func notificationManagerDidUpdateInAppNotifications(_ manager: NotificationManager, notifications: [InAppNotificationDescriptor]) {
+ func notificationManagerDidUpdateInAppNotifications(
+ _ manager: NotificationManager,
+ notifications: [InAppNotificationDescriptor]
+ ) {
connectController?.notificationController.setNotifications(notifications, animated: true)
}
}
@@ -637,10 +655,13 @@ extension SceneDelegate: NotificationManagerDelegate {
// MARK: - SelectLocationViewControllerDelegate
extension SceneDelegate: SelectLocationViewControllerDelegate {
- func selectLocationViewController(_ controller: SelectLocationViewController, didSelectRelayLocation relayLocation: RelayLocation) {
+ func selectLocationViewController(
+ _ controller: SelectLocationViewController,
+ didSelectRelayLocation relayLocation: RelayLocation
+ ) {
// Dismiss view controller in modal presentation
if controller.presentingViewController != nil {
- self.window?.isUserInteractionEnabled = false
+ window?.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250)) {
self.window?.isUserInteractionEnabled = true
controller.dismiss(animated: true) {
@@ -674,8 +695,10 @@ extension SceneDelegate: RevokedDeviceViewControllerDelegate {
// MARK: - UIAdaptivePresentationControllerDelegate
extension SceneDelegate: UIAdaptivePresentationControllerDelegate {
-
- func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
+ func adaptivePresentationStyle(
+ for controller: UIPresentationController,
+ traitCollection: UITraitCollection
+ ) -> UIModalPresentationStyle {
if controller.presentedViewController is RootContainerViewController {
return traitCollection.horizontalSizeClass == .regular ? .formSheet : .fullScreen
} else {
@@ -683,7 +706,11 @@ extension SceneDelegate: UIAdaptivePresentationControllerDelegate {
}
}
- func presentationController(_ presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) {
+ func presentationController(
+ _ presentationController: UIPresentationController,
+ willPresentWithAdaptiveStyle style: UIModalPresentationStyle,
+ transitionCoordinator: UIViewControllerTransitionCoordinator?
+ ) {
let actualStyle: UIModalPresentationStyle
// When adaptive presentation is not changing, the `style` is set to `.none`
@@ -694,7 +721,9 @@ extension SceneDelegate: UIAdaptivePresentationControllerDelegate {
}
// Force hide header bar in .formSheet presentation and show it in .fullScreen presentation
- if let wrapper = presentationController.presentedViewController as? RootContainerViewController {
+ if let wrapper = presentationController
+ .presentedViewController as? RootContainerViewController
+ {
wrapper.setOverrideHeaderBarHidden(actualStyle == .formSheet, animated: false)
}
@@ -734,7 +763,10 @@ extension SceneDelegate: TunnelObserver {
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
@@ -743,7 +775,8 @@ extension SceneDelegate: TunnelObserver {
switch UIDevice.current.userInterfaceIdiom {
case .phone:
- guard let loginController = rootContainer.viewControllers.first as? LoginViewController else {
+ guard let loginController = rootContainer.viewControllers.first as? LoginViewController
+ else {
return
}
@@ -751,13 +784,15 @@ extension SceneDelegate: TunnelObserver {
let viewControllers = [
loginController,
- makeRevokedDeviceController()
+ makeRevokedDeviceController(),
]
rootContainer.setViewControllers(viewControllers, animated: true)
case .pad:
- guard let loginController = modalRootContainer.viewControllers.first as? LoginViewController else {
+ guard let loginController = modalRootContainer.viewControllers
+ .first as? LoginViewController
+ else {
return
}
@@ -765,7 +800,7 @@ extension SceneDelegate: TunnelObserver {
let viewControllers = [
loginController,
- makeRevokedDeviceController()
+ makeRevokedDeviceController(),
]
let didDismissSettings = {
@@ -794,36 +829,41 @@ extension SceneDelegate: TunnelObserver {
// MARK: - RelayCacheObserver
extension SceneDelegate: RelayCacheObserver {
-
- func relayCache(_ relayCache: RelayCache.Tracker, didUpdateCachedRelays cachedRelays: RelayCache.CachedRelays) {
+ func relayCache(
+ _ relayCache: RelayCache.Tracker,
+ didUpdateCachedRelays cachedRelays: RelayCache.CachedRelays
+ ) {
selectLocationViewController?.setCachedRelays(cachedRelays)
}
-
}
-
// MARK: - UISplitViewControllerDelegate
extension SceneDelegate: UISplitViewControllerDelegate {
-
- func primaryViewController(forExpanding splitViewController: UISplitViewController) -> UIViewController? {
+ func primaryViewController(forExpanding splitViewController: UISplitViewController)
+ -> UIViewController?
+ {
// Restore the select location controller as primary when expanding the split view
return selectLocationViewController
}
- func primaryViewController(forCollapsing splitViewController: UISplitViewController) -> UIViewController? {
+ func primaryViewController(forCollapsing splitViewController: UISplitViewController)
+ -> UIViewController?
+ {
// Set the connect controller as primary when collapsing the split view
return connectController
}
- func splitViewController(_ splitViewController: UISplitViewController, separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? {
+ func splitViewController(
+ _ splitViewController: UISplitViewController,
+ separateSecondaryFrom primaryViewController: UIViewController
+ ) -> UIViewController? {
// Dismiss the select location controller when expanding the split view
- if self.selectLocationViewController?.presentingViewController != nil {
- self.selectLocationViewController?.dismiss(animated: false)
+ if selectLocationViewController?.presentingViewController != nil {
+ selectLocationViewController?.dismiss(animated: false)
}
return nil
}
-
}
// MARK: - Window factory
@@ -837,6 +877,7 @@ struct ClassicWindowFactory: WindowFactory {
return UIWindow(frame: UIScreen.main.bounds)
}
}
+
@available(iOS 13.0, *)
struct SceneWindowFactory: WindowFactory {
let windowScene: UIWindowScene
diff --git a/ios/MullvadVPN/SelectLocationCell.swift b/ios/MullvadVPN/SelectLocationCell.swift
index eb52175cd4..c2050560c7 100644
--- a/ios/MullvadVPN/SelectLocationCell.swift
+++ b/ios/MullvadVPN/SelectLocationCell.swift
@@ -23,6 +23,7 @@ class SelectLocationCell: UITableViewCell {
}
return view
}()
+
let tickImageView = UIImageView(image: UIImage(named: "IconTick"))
let collapseButton = UIButton(type: .custom)
@@ -118,9 +119,13 @@ 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
+ [locationLabel, tickImageView, statusIndicator, collapseButton].forEach { subview in
subview.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(subview)
}
@@ -132,7 +137,8 @@ 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),
@@ -140,16 +146,24 @@ class SelectLocationCell: UITableViewCell {
statusIndicator.centerXAnchor.constraint(equalTo: tickImageView.centerXAnchor),
statusIndicator.centerYAnchor.constraint(equalTo: tickImageView.centerYAnchor),
- locationLabel.leadingAnchor.constraint(equalTo: statusIndicator.trailingAnchor, constant: 12),
+ locationLabel.leadingAnchor.constraint(
+ equalTo: statusIndicator.trailingAnchor,
+ constant: 12
+ ),
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(equalToConstant: UIMetrics.contentLayoutMargins.left + UIMetrics.contentLayoutMargins.right + kCollapseButtonWidth),
+ collapseButton.widthAnchor
+ .constraint(
+ equalToConstant: UIMetrics.contentLayoutMargins.left + UIMetrics
+ .contentLayoutMargins.right + kCollapseButtonWidth
+ ),
collapseButton.topAnchor.constraint(equalTo: contentView.topAnchor),
collapseButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
- collapseButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
+ collapseButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
@@ -239,7 +253,11 @@ class SelectLocationCell: UITableViewCell {
)
accessibilityCustomActions = [
- UIAccessibilityCustomAction(name: actionName, target: self, selector: #selector(toggleCollapseAccessibilityAction))
+ UIAccessibilityCustomAction(
+ name: actionName,
+ target: self,
+ selector: #selector(toggleCollapseAccessibilityAction)
+ ),
]
} else {
accessibilityCustomActions = nil
diff --git a/ios/MullvadVPN/SelectLocationHeaderView.swift b/ios/MullvadVPN/SelectLocationHeaderView.swift
index 89e2aa1077..9d39f73bad 100644
--- a/ios/MullvadVPN/SelectLocationHeaderView.swift
+++ b/ios/MullvadVPN/SelectLocationHeaderView.swift
@@ -9,7 +9,6 @@
import UIKit
class SelectLocationHeaderView: UIView {
-
lazy var textContentLabel: UILabel = {
let textLabel = UILabel()
textLabel.translatesAutoresizingMaskIntoConstraints = false
@@ -45,12 +44,11 @@ class SelectLocationHeaderView: UIView {
textContentLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
textContentLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
textContentLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- textContentLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ textContentLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
-
}
diff --git a/ios/MullvadVPN/SelectLocationNavigationController.swift b/ios/MullvadVPN/SelectLocationNavigationController.swift
index 66a5c71fd1..b2e6605aec 100644
--- a/ios/MullvadVPN/SelectLocationNavigationController.swift
+++ b/ios/MullvadVPN/SelectLocationNavigationController.swift
@@ -10,7 +10,6 @@ import Foundation
import UIKit
class SelectLocationNavigationController: UINavigationController {
-
override var childForStatusBarStyle: UIViewController? {
return topViewController
}
diff --git a/ios/MullvadVPN/SelectLocationViewController.swift b/ios/MullvadVPN/SelectLocationViewController.swift
index cf27d8474e..68218c6d92 100644
--- a/ios/MullvadVPN/SelectLocationViewController.swift
+++ b/ios/MullvadVPN/SelectLocationViewController.swift
@@ -6,15 +6,17 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import UIKit
import Logging
+import UIKit
protocol SelectLocationViewControllerDelegate: AnyObject {
- func selectLocationViewController(_ controller: SelectLocationViewController, didSelectRelayLocation relayLocation: RelayLocation)
+ func selectLocationViewController(
+ _ controller: SelectLocationViewController,
+ didSelectRelayLocation relayLocation: RelayLocation
+ )
}
class SelectLocationViewController: UIViewController, UITableViewDelegate {
-
static let cellReuseIdentifier = "Cell"
private var tableView: UITableView?
@@ -71,7 +73,10 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
tableView.estimatedRowHeight = 53
tableView.indicatorStyle = .white
- tableView.register(SelectLocationCell.self, forCellReuseIdentifier: Self.cellReuseIdentifier)
+ tableView.register(
+ SelectLocationCell.self,
+ forCellReuseIdentifier: Self.cellReuseIdentifier
+ )
self.tableView = tableView
@@ -84,10 +89,13 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
dataSource = LocationDataSource(
tableView: tableView,
- cellProvider: { [weak self] (tableView, indexPath, item) -> UITableViewCell? in
+ cellProvider: { [weak self] tableView, indexPath, item -> UITableViewCell? in
guard let self = self else { return nil }
- let cell = tableView.dequeueReusableCell(withIdentifier: Self.cellReuseIdentifier, for: indexPath)
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: Self.cellReuseIdentifier,
+ for: indexPath
+ )
as! SelectLocationCell
cell.accessibilityIdentifier = item.location.stringRepresentation
@@ -95,12 +103,13 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
cell.locationLabel.text = item.displayName
cell.showsCollapseControl = item.isCollapsible
cell.isExpanded = item.showsChildren
- cell.didCollapseHandler = { [weak self] (cell) in
+ cell.didCollapseHandler = { [weak self] cell in
self?.collapseCell(cell)
}
return cell
- })
+ }
+ )
tableView.delegate = self
tableView.dataSource = dataSource
@@ -108,23 +117,23 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
tableHeaderFooterViewTopConstraints = [
tableHeaderFooterView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.topAnchor.constraint(equalTo: tableHeaderFooterView.bottomAnchor),
- tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
]
tableHeaderFooterViewBottomConstraints = [
tableHeaderFooterView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
- tableView.bottomAnchor.constraint(equalTo: tableHeaderFooterView.topAnchor)
+ tableView.bottomAnchor.constraint(equalTo: tableHeaderFooterView.topAnchor),
]
NSLayoutConstraint.activate([
tableHeaderFooterView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableHeaderFooterView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
+ tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
setTableHeaderFooterConstraints()
- if let setCachedRelaysOnViewDidLoad = self.setCachedRelaysOnViewDidLoad {
+ if let setCachedRelaysOnViewDidLoad = setCachedRelaysOnViewDidLoad {
dataSource?.setRelays(setCachedRelaysOnViewDidLoad.relays)
}
@@ -143,10 +152,12 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
// Show header view at the bottom when controller is presented inline and show header view
// at the top of the view when controller is presented modally.
- showHeaderViewAtTheBottom = self.presentingViewController == nil
+ showHeaderViewAtTheBottom = presentingViewController == nil
- if let indexPath = dataSource?.indexPathForSelectedRelay(), scrollToSelectedRelayOnViewWillAppear, !isViewAppeared {
- self.tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
+ if let indexPath = dataSource?.indexPathForSelectedRelay(),
+ scrollToSelectedRelayOnViewWillAppear, !isViewAppeared
+ {
+ tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
}
}
@@ -164,10 +175,13 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
isViewAppeared = false
}
- override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+ override func viewWillTransition(
+ to size: CGSize,
+ with coordinator: UIViewControllerTransitionCoordinator
+ ) {
super.viewWillTransition(to: size, with: coordinator)
- coordinator.animate { (context) in
+ coordinator.animate { context in
if let indexPath = self.dataSource?.indexPathForSelectedRelay() {
self.tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
}
@@ -190,8 +204,14 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
return dataSource?.item(for: indexPath)?.indentationLevel ?? 0
}
- func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
- if let item = dataSource?.item(for: indexPath), item.location == dataSource?.selectedRelayLocation {
+ func tableView(
+ _ tableView: UITableView,
+ willDisplay cell: UITableViewCell,
+ forRowAt indexPath: IndexPath
+ ) {
+ if let item = dataSource?.item(for: indexPath),
+ item.location == dataSource?.selectedRelayLocation
+ {
cell.setSelected(true, animated: false)
}
}
@@ -206,27 +226,31 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
scrollPosition: .none
)
- self.delegate?.selectLocationViewController(self, didSelectRelayLocation: item.location)
+ delegate?.selectLocationViewController(self, didSelectRelayLocation: item.location)
}
// MARK: - Public
func setCachedRelays(_ cachedRelays: RelayCache.CachedRelays) {
guard isViewLoaded else {
- self.setCachedRelaysOnViewDidLoad = cachedRelays
+ setCachedRelaysOnViewDidLoad = cachedRelays
return
}
- self.dataSource?.setRelays(cachedRelays.relays)
+ dataSource?.setRelays(cachedRelays.relays)
}
- func setSelectedRelayLocation(_ relayLocation: RelayLocation?, animated: Bool, scrollPosition: UITableView.ScrollPosition) {
+ func setSelectedRelayLocation(
+ _ relayLocation: RelayLocation?,
+ animated: Bool,
+ scrollPosition: UITableView.ScrollPosition
+ ) {
guard isViewLoaded else {
- self.setRelayLocationOnViewDidLoad = relayLocation
- self.setScrollPositionOnViewDidLoad = scrollPosition
+ setRelayLocationOnViewDidLoad = relayLocation
+ setScrollPositionOnViewDidLoad = scrollPosition
return
}
- self.dataSource?.setSelectedRelayLocation(
+ dataSource?.setSelectedRelayLocation(
relayLocation,
showHiddenParents: true,
animated: animated,
@@ -238,7 +262,9 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
private func collapseCell(_ cell: SelectLocationCell) {
guard let cellIndexPath = tableView?.indexPath(for: cell),
- let dataSource = dataSource, let location = dataSource.relayLocation(for: cellIndexPath) else {
+ let dataSource = dataSource,
+ let location = dataSource.relayLocation(for: cellIndexPath)
+ else {
return
}
@@ -250,8 +276,11 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
private func updateTableHeaderTopLayoutMargin() {
// When contained within the navigation controller, we want the distance between the navigation title
// and the table header label to be exactly 24pt.
- if let navigationBar = navigationController?.navigationBar as? CustomNavigationBar, !showHeaderViewAtTheBottom {
- tableHeaderFooterView.topLayoutMarginAdjustmentForNavigationBarTitle = navigationBar.titleLabelBottomInset
+ if let navigationBar = navigationController?.navigationBar as? CustomNavigationBar,
+ !showHeaderViewAtTheBottom
+ {
+ tableHeaderFooterView.topLayoutMarginAdjustmentForNavigationBarTitle = navigationBar
+ .titleLabelBottomInset
} else {
tableHeaderFooterView.topLayoutMarginAdjustmentForNavigationBarTitle = 0
}
@@ -260,11 +289,13 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
private func setTableHeaderFooterConstraints() {
if showHeaderViewAtTheBottom {
NSLayoutConstraint.deactivate(
- tableHeaderFooterViewTopConstraints)
+ tableHeaderFooterViewTopConstraints
+ )
NSLayoutConstraint.activate(tableHeaderFooterViewBottomConstraints)
} else {
NSLayoutConstraint.deactivate(
- tableHeaderFooterViewBottomConstraints)
+ tableHeaderFooterViewBottomConstraints
+ )
NSLayoutConstraint.activate(tableHeaderFooterViewTopConstraints)
}
view.layoutIfNeeded()
diff --git a/ios/MullvadVPN/SettingsAccountCell.swift b/ios/MullvadVPN/SettingsAccountCell.swift
index 6021e4cca2..f0621f31dc 100644
--- a/ios/MullvadVPN/SettingsAccountCell.swift
+++ b/ios/MullvadVPN/SettingsAccountCell.swift
@@ -9,7 +9,6 @@
import UIKit
class SettingsAccountCell: SettingsCell {
-
var accountExpiryDate: Date? {
didSet {
didUpdateAccountExpiry()
diff --git a/ios/MullvadVPN/SettingsAddDNSEntryCell.swift b/ios/MullvadVPN/SettingsAddDNSEntryCell.swift
index a2db42e6ba..3aaadd90f7 100644
--- a/ios/MullvadVPN/SettingsAddDNSEntryCell.swift
+++ b/ios/MullvadVPN/SettingsAddDNSEntryCell.swift
@@ -16,7 +16,10 @@ class SettingsAddDNSEntryCell: SettingsCell {
backgroundView?.backgroundColor = UIColor.SubSubCell.backgroundColor
- let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
+ let gestureRecognizer = UITapGestureRecognizer(
+ target: self,
+ action: #selector(handleTap(_:))
+ )
contentView.addGestureRecognizer(gestureRecognizer)
}
diff --git a/ios/MullvadVPN/SettingsCell.swift b/ios/MullvadVPN/SettingsCell.swift
index 2bb7a8a43f..3aaf1ee67b 100644
--- a/ios/MullvadVPN/SettingsCell.swift
+++ b/ios/MullvadVPN/SettingsCell.swift
@@ -26,7 +26,6 @@ enum SettingsDisclosureType {
}
class SettingsCell: UITableViewCell {
-
let titleLabel = UILabel()
let detailTitleLabel = UILabel()
let disclosureImageView = UIImageView(image: nil)
@@ -83,15 +82,23 @@ class SettingsCell: UITableViewCell {
setLayoutMargins()
NSLayoutConstraint.activate([
- titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
+ titleLabel.leadingAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
titleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
- titleLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
+ titleLabel.bottomAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
- detailTitleLabel.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: titleLabel.trailingAnchor, multiplier: 1),
+ detailTitleLabel.leadingAnchor.constraint(
+ greaterThanOrEqualToSystemSpacingAfter: titleLabel.trailingAnchor,
+ multiplier: 1
+ ),
- detailTitleLabel.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
- detailTitleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
- detailTitleLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
+ detailTitleLabel.trailingAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
+ detailTitleLabel.topAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
+ detailTitleLabel.bottomAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
])
}
@@ -134,7 +141,9 @@ class SettingsCell: UITableViewCell {
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 {
+ 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
diff --git a/ios/MullvadVPN/SettingsDNSTextCell.swift b/ios/MullvadVPN/SettingsDNSTextCell.swift
index 1d459c9229..dd1a97ccd3 100644
--- a/ios/MullvadVPN/SettingsDNSTextCell.swift
+++ b/ios/MullvadVPN/SettingsDNSTextCell.swift
@@ -10,8 +10,7 @@ import Foundation
import UIKit
class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate {
-
- var isValidInput: Bool = true {
+ var isValidInput = true {
didSet {
updateCellAppearance(animated: false)
}
@@ -65,7 +64,7 @@ class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate {
textField.topAnchor.constraint(equalTo: contentView.topAnchor),
textField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
textField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
- textField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
+ textField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
updateCellAppearance(animated: false)
@@ -130,7 +129,11 @@ class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate {
return true
}
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
+ func textField(
+ _ textField: UITextField,
+ shouldChangeCharactersIn range: NSRange,
+ replacementString string: String
+ ) -> Bool {
let ipv4AddressCharset = CharacterSet.ipv4AddressCharset
let ipv6AddressCharset = CharacterSet.ipv6AddressCharset
@@ -140,5 +143,4 @@ class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate {
}
}
}
-
}
diff --git a/ios/MullvadVPN/SettingsDataSource.swift b/ios/MullvadVPN/SettingsDataSource.swift
index 203d446b5f..1a9caf3389 100644
--- a/ios/MullvadVPN/SettingsDataSource.swift
+++ b/ios/MullvadVPN/SettingsDataSource.swift
@@ -74,11 +74,17 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
private func registerClasses() {
CellReuseIdentifiers.allCases.forEach { cellIdentifier in
- tableView?.register(cellIdentifier.reusableViewClass, forCellReuseIdentifier: cellIdentifier.rawValue)
+ tableView?.register(
+ cellIdentifier.reusableViewClass,
+ forCellReuseIdentifier: cellIdentifier.rawValue
+ )
}
HeaderFooterReuseIdentifier.allCases.forEach { reuseIdentifier in
- tableView?.register(reuseIdentifier.reusableViewClass, forHeaderFooterViewReuseIdentifier: reuseIdentifier.rawValue)
+ tableView?.register(
+ reuseIdentifier.reusableViewClass,
+ forHeaderFooterViewReuseIdentifier: reuseIdentifier.rawValue
+ )
}
}
@@ -114,7 +120,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
switch item {
case .account:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.accountCell.rawValue, for: indexPath) as! SettingsAccountCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.accountCell.rawValue,
+ for: indexPath
+ ) as! SettingsAccountCell
cell.titleLabel.text = NSLocalizedString(
"ACCOUNT_CELL_LABEL",
tableName: "Settings",
@@ -128,7 +137,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
return cell
case .preferences:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.basicCell.rawValue, for: indexPath) as! SettingsCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.basicCell.rawValue,
+ for: indexPath
+ ) as! SettingsCell
cell.titleLabel.text = NSLocalizedString(
"PREFERENCES_CELL_LABEL",
tableName: "Settings",
@@ -142,7 +154,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
return cell
case .wireguardKey:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.basicCell.rawValue, for: indexPath) as! SettingsCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.basicCell.rawValue,
+ for: indexPath
+ ) as! SettingsCell
cell.titleLabel.text = NSLocalizedString(
"WIREGUARD_KEY_CELL_LABEL",
tableName: "Settings",
@@ -156,7 +171,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
return cell
case .version:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.basicCell.rawValue, for: indexPath) as! SettingsCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.basicCell.rawValue,
+ for: indexPath
+ ) as! SettingsCell
cell.titleLabel.text = NSLocalizedString(
"APP_VERSION_CELL_LABEL",
tableName: "Settings",
@@ -170,7 +188,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
return cell
case .problemReport:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.basicCell.rawValue, for: indexPath) as! SettingsCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.basicCell.rawValue,
+ for: indexPath
+ ) as! SettingsCell
cell.titleLabel.text = NSLocalizedString(
"REPORT_PROBLEM_CELL_LABEL",
tableName: "Settings",
@@ -184,7 +205,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
return cell
case .faq:
- let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.basicCell.rawValue, for: indexPath) as! SettingsCell
+ let cell = tableView.dequeueReusableCell(
+ withIdentifier: CellReuseIdentifiers.basicCell.rawValue,
+ for: indexPath
+ ) as! SettingsCell
cell.titleLabel.text = NSLocalizedString(
"FAQ_AND_GUIDES_CELL_LABEL",
tableName: "Settings",
@@ -196,7 +220,6 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
cell.disclosureType = .externalLink
return cell
-
}
}
@@ -217,7 +240,11 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
- return tableView.dequeueReusableHeaderFooterView(withIdentifier: HeaderFooterReuseIdentifier.spacer.rawValue)
+ return tableView
+ .dequeueReusableHeaderFooterView(
+ withIdentifier: HeaderFooterReuseIdentifier.spacer
+ .rawValue
+ )
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
@@ -255,7 +282,8 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
// Refresh individual row if expiry changed.
if let newAccountData = newAccountData, let oldAccountData = oldAccountData,
oldAccountData.number == newAccountData.number,
- oldAccountData.expiry != newAccountData.expiry {
+ oldAccountData.expiry != newAccountData.expiry
+ {
tableView?.performBatchUpdates {
if let indexPath = snapshot.indexPathForItem(.account) {
tableView?.reloadRows(at: [indexPath], with: .none)
@@ -268,7 +296,10 @@ class SettingsDataSource: NSObject, TunnelObserver, UITableViewDataSource, UITab
tableView?.reloadData()
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
// no-op
}
}
diff --git a/ios/MullvadVPN/SettingsDataSourceDelegate.swift b/ios/MullvadVPN/SettingsDataSourceDelegate.swift
index 739c6d4552..30d7e1629a 100644
--- a/ios/MullvadVPN/SettingsDataSourceDelegate.swift
+++ b/ios/MullvadVPN/SettingsDataSourceDelegate.swift
@@ -9,5 +9,8 @@
import UIKit
protocol SettingsDataSourceDelegate: AnyObject {
- func settingsDataSource(_ dataSource: SettingsDataSource, didSelectItem item: SettingsDataSource.Item)
+ func settingsDataSource(
+ _ dataSource: SettingsDataSource,
+ didSelectItem item: SettingsDataSource.Item
+ )
}
diff --git a/ios/MullvadVPN/SettingsManager/SettingsManager.swift b/ios/MullvadVPN/SettingsManager/SettingsManager.swift
index 54aa293615..95af7b2a99 100644
--- a/ios/MullvadVPN/SettingsManager/SettingsManager.swift
+++ b/ios/MullvadVPN/SettingsManager/SettingsManager.swift
@@ -41,7 +41,6 @@ struct StringEncodingError: LocalizedError {
}
extension SettingsManager {
-
// MARK: - Lsat used account
static func getLastUsedAccount() throws -> String {
@@ -104,7 +103,6 @@ extension SettingsManager {
try addOrUpdateItem(.deviceState, data: data)
}
-
static func deleteDeviceState() throws {
try deleteItem(.deviceState)
}
@@ -135,6 +133,7 @@ extension SettingsManager {
throw KeychainError(code: status)
}
}
+
private static func addOrUpdateItem(_ item: Item, data: Data) throws {
do {
try updateItem(item, data: data)
@@ -167,18 +166,18 @@ extension SettingsManager {
}
}
- private static func createDefaultAttributes(item: Item) -> [CFString: Any] {
+ private static func createDefaultAttributes(item: Item) -> [CFString: Any] {
return [
kSecClass: kSecClassGenericPassword,
kSecAttrService: keychainServiceName,
- kSecAttrAccount: item.rawValue
+ kSecAttrAccount: item.rawValue,
]
}
private static func createAccessAttributes() -> [CFString: Any] {
return [
kSecAttrAccessGroup: ApplicationConfiguration.securityGroupIdentifier,
- kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock
+ kSecAttrAccessible: kSecAttrAccessibleAfterFirstUnlock,
]
}
@@ -192,7 +191,7 @@ extension SettingsManager {
kSecAttrService: keychainServiceName,
kSecReturnAttributes: true,
kSecReturnData: true,
- kSecMatchLimit: kSecMatchLimitAll
+ kSecMatchLimit: kSecMatchLimitAll,
]
var result: CFTypeRef?
@@ -209,9 +208,10 @@ extension SettingsManager {
return items.filter(Self.filterLegacySettings)
.compactMap { item -> LegacyTunnelSettings? in
guard let accountNumber = item[kSecAttrAccount] as? String,
- let data = item[kSecValueData] as? Data else {
- return nil
- }
+ let data = item[kSecValueData] as? Data
+ else {
+ return nil
+ }
do {
let tunnelSettings = try JSONDecoder().decode(
TunnelSettingsV1.self,
@@ -237,7 +237,7 @@ extension SettingsManager {
kSecClass: kSecClassGenericPassword,
kSecAttrService: keychainServiceName,
kSecReturnAttributes: true,
- kSecMatchLimit: kSecMatchLimitAll
+ kSecMatchLimit: kSecMatchLimitAll,
]
var result: CFTypeRef?
@@ -262,7 +262,7 @@ extension SettingsManager {
items.filter(Self.filterLegacySettings)
.enumerated()
- .forEach { (index, item) in
+ .forEach { index, item in
guard let account = item[kSecAttrAccount] else {
return
}
@@ -270,7 +270,7 @@ extension SettingsManager {
let deleteQuery: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: keychainServiceName,
- kSecAttrAccount: account
+ kSecAttrAccount: account,
]
let status = SecItemDelete(deleteQuery as CFDictionary)
diff --git a/ios/MullvadVPN/SettingsManager/TunnelSettingsV1.swift b/ios/MullvadVPN/SettingsManager/TunnelSettingsV1.swift
index 0d7facb554..b5a8ed207f 100644
--- a/ios/MullvadVPN/SettingsManager/TunnelSettingsV1.swift
+++ b/ios/MullvadVPN/SettingsManager/TunnelSettingsV1.swift
@@ -8,9 +8,9 @@
import Foundation
import struct Network.IPv4Address
-import class WireGuardKitTypes.PublicKey
-import class WireGuardKitTypes.PrivateKey
import struct WireGuardKitTypes.IPAddressRange
+import class WireGuardKitTypes.PrivateKey
+import class WireGuardKitTypes.PublicKey
/// A struct that holds the configuration passed via `NETunnelProviderProtocol`.
struct TunnelSettingsV1: Codable, Equatable {
@@ -35,8 +35,7 @@ struct InterfaceSettings: Codable, Equatable {
nextPrivateKey: PrivateKeyWithMetadata? = nil,
addresses: [IPAddressRange] = [],
dnsSettings: DNSSettings = DNSSettings()
- )
- {
+ ) {
self.privateKey = privateKey
self.nextPrivateKey = nextPrivateKey
self.addresses = addresses
@@ -50,7 +49,10 @@ struct InterfaceSettings: Codable, Equatable {
addresses = try container.decode([IPAddressRange].self, forKey: .addresses)
// Added in 2022.1
- nextPrivateKey = try container.decodeIfPresent(PrivateKeyWithMetadata.self, forKey: .nextPrivateKey)
+ nextPrivateKey = try container.decodeIfPresent(
+ PrivateKeyWithMetadata.self,
+ forKey: .nextPrivateKey
+ )
// Provide default value, since `dnsSettings` key does not exist in <= 2021.2
dnsSettings = try container.decodeIfPresent(DNSSettings.self, forKey: .dnsSettings)
diff --git a/ios/MullvadVPN/SettingsManager/TunnelSettingsV2.swift b/ios/MullvadVPN/SettingsManager/TunnelSettingsV2.swift
index d21194c92f..c38dc00ddb 100644
--- a/ios/MullvadVPN/SettingsManager/TunnelSettingsV2.swift
+++ b/ios/MullvadVPN/SettingsManager/TunnelSettingsV2.swift
@@ -8,16 +8,16 @@
import Foundation
import struct Network.IPv4Address
-import class WireGuardKitTypes.PublicKey
-import class WireGuardKitTypes.PrivateKey
import struct WireGuardKitTypes.IPAddressRange
+import class WireGuardKitTypes.PrivateKey
+import class WireGuardKitTypes.PublicKey
struct TunnelSettingsV2: Codable, Equatable {
/// Relay constraints.
- var relayConstraints: RelayConstraints = RelayConstraints()
+ var relayConstraints = RelayConstraints()
/// DNS settings.
- var dnsSettings: DNSSettings = DNSSettings()
+ var dnsSettings = DNSSettings()
}
struct StoredAccountData: Codable, Equatable {
@@ -52,7 +52,7 @@ enum DeviceState: Codable, Equatable {
var accountData: StoredAccountData? {
switch self {
- case .loggedIn(let accountData, _):
+ case let .loggedIn(accountData, _):
return accountData
case .loggedOut, .revoked:
return nil
@@ -61,7 +61,7 @@ enum DeviceState: Codable, Equatable {
var deviceData: StoredDeviceData? {
switch self {
- case .loggedIn(_, let deviceData):
+ case let .loggedIn(_, deviceData):
return deviceData
case .loggedOut, .revoked:
return nil
diff --git a/ios/MullvadVPN/SettingsNavigationController.swift b/ios/MullvadVPN/SettingsNavigationController.swift
index b916561373..6611759c48 100644
--- a/ios/MullvadVPN/SettingsNavigationController.swift
+++ b/ios/MullvadVPN/SettingsNavigationController.swift
@@ -22,11 +22,15 @@ enum SettingsDismissReason {
}
protocol SettingsNavigationControllerDelegate: AnyObject {
- func settingsNavigationController(_ controller: SettingsNavigationController, didFinishWithReason reason: SettingsDismissReason)
+ func settingsNavigationController(
+ _ controller: SettingsNavigationController,
+ didFinishWithReason reason: SettingsDismissReason
+ )
}
-class SettingsNavigationController: CustomNavigationController, SettingsViewControllerDelegate, AccountViewControllerDelegate, UIAdaptivePresentationControllerDelegate {
-
+class SettingsNavigationController: CustomNavigationController, SettingsViewControllerDelegate,
+ AccountViewControllerDelegate, UIAdaptivePresentationControllerDelegate
+{
weak var settingsDelegate: SettingsNavigationControllerDelegate?
override var childForStatusBarStyle: UIViewController? {
@@ -68,20 +72,20 @@ class SettingsNavigationController: CustomNavigationController, SettingsViewCont
// MARK: - SettingsViewControllerDelegate
func settingsViewControllerDidFinish(_ controller: SettingsViewController) {
- self.settingsDelegate?.settingsNavigationController(self, didFinishWithReason: .none)
+ settingsDelegate?.settingsNavigationController(self, didFinishWithReason: .none)
}
// MARK: - AccountViewControllerDelegate
func accountViewControllerDidLogout(_ controller: AccountViewController) {
- self.settingsDelegate?.settingsNavigationController(self, didFinishWithReason: .userLoggedOut)
+ settingsDelegate?.settingsNavigationController(self, didFinishWithReason: .userLoggedOut)
}
// MARK: - Navigation
func navigate(to route: SettingsNavigationRoute, animated: Bool) {
let nextViewController = makeViewController(for: route)
- if let rootController = self.viewControllers.first, viewControllers.count > 1 {
+ if let rootController = viewControllers.first, viewControllers.count > 1 {
setViewControllers([rootController, nextViewController], animated: animated)
} else {
pushViewController(nextViewController, animated: animated)
diff --git a/ios/MullvadVPN/SettingsStaticTextFooterView.swift b/ios/MullvadVPN/SettingsStaticTextFooterView.swift
index 7e5619fb4d..700d31dc78 100644
--- a/ios/MullvadVPN/SettingsStaticTextFooterView.swift
+++ b/ios/MullvadVPN/SettingsStaticTextFooterView.swift
@@ -26,10 +26,12 @@ class SettingsStaticTextFooterView: UITableViewHeaderFooterView {
contentView.addConstraints([
titleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
- titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
- titleLabel.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
+ titleLabel.leadingAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
+ titleLabel.trailingAnchor
+ .constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
titleLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor)
- .withPriority(.defaultLow)
+ .withPriority(.defaultLow),
])
}
diff --git a/ios/MullvadVPN/SettingsSwitchCell.swift b/ios/MullvadVPN/SettingsSwitchCell.swift
index a504726dff..5b81c186b4 100644
--- a/ios/MullvadVPN/SettingsSwitchCell.swift
+++ b/ios/MullvadVPN/SettingsSwitchCell.swift
@@ -9,7 +9,6 @@
import UIKit
class SettingsSwitchCell: SettingsCell {
-
private let switchContainer = CustomSwitchContainer()
var action: ((Bool) -> Void)?
@@ -19,7 +18,11 @@ class SettingsSwitchCell: SettingsCell {
accessoryView = switchContainer
- switchContainer.control.addTarget(self, action: #selector(switchValueDidChange), for: .valueChanged)
+ switchContainer.control.addTarget(
+ self,
+ action: #selector(switchValueDidChange),
+ for: .valueChanged
+ )
isAccessibilityElement = true
}
@@ -45,7 +48,7 @@ class SettingsSwitchCell: SettingsCell {
// MARK: - Actions
@objc private func switchValueDidChange() {
- action?(self.switchContainer.control.isOn)
+ action?(switchContainer.control.isOn)
}
// MARK: - Accessibility
@@ -99,7 +102,7 @@ class SettingsSwitchCell: SettingsCell {
override func accessibilityActivate() -> Bool {
guard switchContainer.isEnabled else { return false }
- let newValue = !self.switchContainer.control.isOn
+ let newValue = !switchContainer.control.isOn
setOn(newValue, animated: true)
action?(newValue)
diff --git a/ios/MullvadVPN/SettingsViewController.swift b/ios/MullvadVPN/SettingsViewController.swift
index e6dd7490a7..6fa1bbf045 100644
--- a/ios/MullvadVPN/SettingsViewController.swift
+++ b/ios/MullvadVPN/SettingsViewController.swift
@@ -14,8 +14,9 @@ protocol SettingsViewControllerDelegate: AnyObject {
func settingsViewControllerDidFinish(_ controller: SettingsViewController)
}
-class SettingsViewController: UITableViewController, SettingsDataSourceDelegate, SFSafariViewControllerDelegate {
-
+class SettingsViewController: UITableViewController, SettingsDataSourceDelegate,
+ SFSafariViewControllerDelegate
+{
weak var delegate: SettingsViewControllerDelegate?
override var preferredStatusBarStyle: UIStatusBarStyle {
@@ -42,7 +43,11 @@ class SettingsViewController: UITableViewController, SettingsDataSourceDelegate,
comment: ""
)
navigationItem.largeTitleDisplayMode = .always
- navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDismiss))
+ navigationItem.rightBarButtonItem = UIBarButtonItem(
+ barButtonSystemItem: .done,
+ target: self,
+ action: #selector(handleDismiss)
+ )
tableView.backgroundColor = .secondaryColor
tableView.separatorColor = .secondaryColor
@@ -61,13 +66,19 @@ class SettingsViewController: UITableViewController, SettingsDataSourceDelegate,
// MARK: - SettingsDataSourceDelegate
- func settingsDataSource(_ dataSource: SettingsDataSource, didSelectItem item: SettingsDataSource.Item) {
+ func settingsDataSource(
+ _ dataSource: SettingsDataSource,
+ didSelectItem item: SettingsDataSource.Item
+ ) {
if let route = item.navigationRoute {
let settingsNavigationController = navigationController as? SettingsNavigationController
settingsNavigationController?.navigate(to: route, animated: true)
} else if case .faq = item {
- let safariViewController = SFSafariViewController(url: ApplicationConfiguration.faqAndGuidesURL)
+ let safariViewController = SFSafariViewController(
+ url: ApplicationConfiguration
+ .faqAndGuidesURL
+ )
safariViewController.delegate = self
present(safariViewController, animated: true)
diff --git a/ios/MullvadVPN/SimulatorTunnelProvider.swift b/ios/MullvadVPN/SimulatorTunnelProvider.swift
index 657337f82c..162a95590f 100644
--- a/ios/MullvadVPN/SimulatorTunnelProvider.swift
+++ b/ios/MullvadVPN/SimulatorTunnelProvider.swift
@@ -48,374 +48,388 @@ extension NETunnelProviderManager: VPNTunnelProviderManagerProtocol {}
#if targetEnvironment(simulator)
-// MARK: - NEPacketTunnelProvider stubs
+ // MARK: - NEPacketTunnelProvider stubs
-class SimulatorTunnelProviderDelegate {
- fileprivate(set) var connection: SimulatorVPNConnection?
+ class SimulatorTunnelProviderDelegate {
+ fileprivate(set) var connection: SimulatorVPNConnection?
- var protocolConfiguration: NEVPNProtocol {
- return connection?.protocolConfiguration ?? NEVPNProtocol()
- }
-
- var reasserting: Bool {
- get {
- return connection?.reasserting ?? false
+ var protocolConfiguration: NEVPNProtocol {
+ return connection?.protocolConfiguration ?? NEVPNProtocol()
}
- set {
- connection?.reasserting = newValue
+
+ var reasserting: Bool {
+ get {
+ return connection?.reasserting ?? false
+ }
+ set {
+ connection?.reasserting = newValue
+ }
}
- }
- func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
- completionHandler(nil)
- }
+ func startTunnel(
+ options: [String: NSObject]?,
+ completionHandler: @escaping (Error?) -> Void
+ ) {
+ completionHandler(nil)
+ }
- func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
- completionHandler()
- }
+ func stopTunnel(
+ with reason: NEProviderStopReason,
+ completionHandler: @escaping () -> Void
+ ) {
+ completionHandler()
+ }
- func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
- completionHandler?(nil)
+ func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
+ completionHandler?(nil)
+ }
}
-}
-class SimulatorTunnelProvider {
- static let shared = SimulatorTunnelProvider()
+ class SimulatorTunnelProvider {
+ static let shared = SimulatorTunnelProvider()
- private let lock = NSLock()
- private var _delegate: SimulatorTunnelProviderDelegate?
+ private let lock = NSLock()
+ private var _delegate: SimulatorTunnelProviderDelegate?
- var delegate: SimulatorTunnelProviderDelegate! {
- get {
- lock.lock()
- defer { lock.unlock() }
+ var delegate: SimulatorTunnelProviderDelegate! {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return _delegate
- }
- set {
- lock.lock()
- _delegate = newValue
- lock.unlock()
+ return _delegate
+ }
+ set {
+ lock.lock()
+ _delegate = newValue
+ lock.unlock()
+ }
}
- }
- private init() {}
+ private init() {}
- fileprivate func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
- self.delegate.handleAppMessage(messageData, completionHandler: completionHandler)
+ fileprivate func handleAppMessage(
+ _ messageData: Data,
+ completionHandler: ((Data?) -> Void)? = nil
+ ) {
+ delegate.handleAppMessage(messageData, completionHandler: completionHandler)
+ }
}
-}
-// MARK: - NEVPNConnection stubs
+ // MARK: - NEVPNConnection stubs
-class SimulatorVPNConnection: NSObject, VPNConnectionProtocol {
- // Protocol configuration is automatically synced by `SimulatorTunnelInfo`
- fileprivate var protocolConfiguration = NEVPNProtocol()
+ class SimulatorVPNConnection: NSObject, VPNConnectionProtocol {
+ // Protocol configuration is automatically synced by `SimulatorTunnelInfo`
+ fileprivate var protocolConfiguration = NEVPNProtocol()
- private let lock = NSRecursiveLock()
- private var _status: NEVPNStatus = .disconnected
- private var _reasserting = false
- private var _connectedDate: Date?
+ private let lock = NSRecursiveLock()
+ private var _status: NEVPNStatus = .disconnected
+ private var _reasserting = false
+ private var _connectedDate: Date?
- private(set) var status: NEVPNStatus {
- get {
- lock.lock()
- defer { lock.unlock() }
+ private(set) var status: NEVPNStatus {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return _status
- }
- set {
- lock.lock()
+ return _status
+ }
+ set {
+ lock.lock()
- if _status != newValue {
- _status = newValue
+ if _status != newValue {
+ _status = newValue
- // Send notification while holding the lock. This should enable the receiver
- // to fetch the `SimulatorVPNConnection.status` before the concurrent code gets
- // opportunity to change it again.
- postStatusDidChangeNotification()
- }
+ // Send notification while holding the lock. This should enable the receiver
+ // to fetch the `SimulatorVPNConnection.status` before the concurrent code gets
+ // opportunity to change it again.
+ postStatusDidChangeNotification()
+ }
- lock.unlock()
+ lock.unlock()
+ }
}
- }
- var reasserting: Bool {
- get {
- lock.lock()
- defer { lock.unlock() }
+ var reasserting: Bool {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return _reasserting
- }
- set {
- lock.lock()
+ return _reasserting
+ }
+ set {
+ lock.lock()
- if _reasserting != newValue {
- _reasserting = newValue
+ if _reasserting != newValue {
+ _reasserting = newValue
- if newValue {
- status = .reasserting
- } else {
- status = .connected
+ if newValue {
+ status = .reasserting
+ } else {
+ status = .connected
+ }
}
- }
- lock.unlock()
+ lock.unlock()
+ }
}
- }
- private(set) var connectedDate: Date? {
- get {
- lock.lock()
- defer { lock.unlock() }
+ private(set) var connectedDate: Date? {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return _connectedDate
+ return _connectedDate
+ }
+ set {
+ lock.lock()
+ _connectedDate = newValue
+ lock.unlock()
+ }
}
- set {
- lock.lock()
- _connectedDate = newValue
- lock.unlock()
+
+ func startVPNTunnel() throws {
+ try startVPNTunnel(options: nil)
}
- }
- func startVPNTunnel() throws {
- try startVPNTunnel(options: nil)
- }
+ func startVPNTunnel(options: [String: NSObject]?) throws {
+ SimulatorTunnelProvider.shared.delegate.connection = self
- func startVPNTunnel(options: [String: NSObject]?) throws {
- SimulatorTunnelProvider.shared.delegate.connection = self
+ status = .connecting
- status = .connecting
+ SimulatorTunnelProvider.shared.delegate.startTunnel(options: options) { error in
+ if error == nil {
+ self.status = .connected
+ self.connectedDate = Date()
+ } else {
+ self.status = .disconnected
+ self.connectedDate = nil
+ }
+ }
+ }
- SimulatorTunnelProvider.shared.delegate.startTunnel(options: options) { error in
- if error == nil {
- self.status = .connected
- self.connectedDate = Date()
- } else {
+ func stopVPNTunnel() {
+ status = .disconnecting
+
+ SimulatorTunnelProvider.shared.delegate.stopTunnel(with: .userInitiated) {
self.status = .disconnected
self.connectedDate = nil
}
}
- }
-
- func stopVPNTunnel() {
- status = .disconnecting
- SimulatorTunnelProvider.shared.delegate.stopTunnel(with: .userInitiated) {
- self.status = .disconnected
- self.connectedDate = nil
+ private func postStatusDidChangeNotification() {
+ NotificationCenter.default.post(name: .NEVPNStatusDidChange, object: self)
}
}
- private func postStatusDidChangeNotification() {
- NotificationCenter.default.post(name: .NEVPNStatusDidChange, object: self)
- }
-}
-
-// MARK: - NETunnelProviderSession stubs
-
-class SimulatorTunnelProviderSession: SimulatorVPNConnection, VPNTunnelProviderSessionProtocol {
+ // MARK: - NETunnelProviderSession stubs
- func sendProviderMessage(_ messageData: Data, responseHandler: ((Data?) -> Void)?) throws {
- SimulatorTunnelProvider.shared.handleAppMessage(messageData, completionHandler: responseHandler)
+ class SimulatorTunnelProviderSession: SimulatorVPNConnection, VPNTunnelProviderSessionProtocol {
+ func sendProviderMessage(_ messageData: Data, responseHandler: ((Data?) -> Void)?) throws {
+ SimulatorTunnelProvider.shared.handleAppMessage(
+ messageData,
+ completionHandler: responseHandler
+ )
+ }
}
-}
-
-// MARK: - NETunnelProviderManager stubs
+ // MARK: - NETunnelProviderManager stubs
-/// A mock struct for tunnel configuration and connection
-private struct SimulatorTunnelInfo {
- /// A unique identifier for the configuration
- var identifier = UUID().uuidString
+ /// A mock struct for tunnel configuration and connection
+ private struct SimulatorTunnelInfo {
+ /// A unique identifier for the configuration
+ var identifier = UUID().uuidString
- /// An associated VPN connection.
- /// Intentionally initialized with a `SimulatorTunnelProviderSession` subclass which
- /// implements the necessary protocol
- var connection: SimulatorVPNConnection = SimulatorTunnelProviderSession()
+ /// An associated VPN connection.
+ /// Intentionally initialized with a `SimulatorTunnelProviderSession` subclass which
+ /// implements the necessary protocol
+ var connection: SimulatorVPNConnection = SimulatorTunnelProviderSession()
- /// Whether configuration is enabled
- var isEnabled = false
+ /// Whether configuration is enabled
+ var isEnabled = false
- /// Whether on-demand VPN is enabled
- var isOnDemandEnabled = false
+ /// Whether on-demand VPN is enabled
+ var isOnDemandEnabled = false
- /// On-demand VPN rules
- var onDemandRules = [NEOnDemandRule]()
+ /// On-demand VPN rules
+ var onDemandRules = [NEOnDemandRule]()
- /// Protocol configuration
- var protocolConfiguration: NEVPNProtocol? {
- didSet {
- self.connection.protocolConfiguration = protocolConfiguration ?? NEVPNProtocol()
+ /// Protocol configuration
+ var protocolConfiguration: NEVPNProtocol? {
+ didSet {
+ connection.protocolConfiguration = protocolConfiguration ?? NEVPNProtocol()
+ }
}
- }
-
- /// Tunnel description
- var localizedDescription: String?
-
- /// Designated initializer
- init() {}
-}
-
-class SimulatorTunnelProviderManager: VPNTunnelProviderManagerProtocol, Equatable {
- static let tunnelsLock = NSRecursiveLock()
- fileprivate static var tunnels = [SimulatorTunnelInfo]()
+ /// Tunnel description
+ var localizedDescription: String?
- private let lock = NSLock()
- private var tunnelInfo: SimulatorTunnelInfo
- private var identifier: String {
- lock.lock()
- defer { lock.unlock() }
-
- return tunnelInfo.identifier
+ /// Designated initializer
+ init() {}
}
- var isOnDemandEnabled: Bool {
- get {
+ class SimulatorTunnelProviderManager: VPNTunnelProviderManagerProtocol, Equatable {
+ static let tunnelsLock = NSRecursiveLock()
+ fileprivate static var tunnels = [SimulatorTunnelInfo]()
+
+ private let lock = NSLock()
+ private var tunnelInfo: SimulatorTunnelInfo
+ private var identifier: String {
lock.lock()
defer { lock.unlock() }
- return tunnelInfo.isOnDemandEnabled
+ return tunnelInfo.identifier
}
- set {
- lock.lock()
- tunnelInfo.isOnDemandEnabled = newValue
- lock.unlock()
- }
- }
- var onDemandRules: [NEOnDemandRule] {
- get {
- lock.lock()
- defer { lock.unlock() }
+ var isOnDemandEnabled: Bool {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return tunnelInfo.onDemandRules
- }
- set {
- lock.lock()
- tunnelInfo.onDemandRules = newValue
- lock.unlock()
+ return tunnelInfo.isOnDemandEnabled
+ }
+ set {
+ lock.lock()
+ tunnelInfo.isOnDemandEnabled = newValue
+ lock.unlock()
+ }
}
- }
- var isEnabled: Bool {
- get {
- lock.lock()
- defer { lock.unlock() }
+ var onDemandRules: [NEOnDemandRule] {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return tunnelInfo.isEnabled
+ return tunnelInfo.onDemandRules
+ }
+ set {
+ lock.lock()
+ tunnelInfo.onDemandRules = newValue
+ lock.unlock()
+ }
}
- set {
- lock.lock()
- tunnelInfo.isEnabled = newValue
- lock.unlock()
+
+ var isEnabled: Bool {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
+
+ return tunnelInfo.isEnabled
+ }
+ set {
+ lock.lock()
+ tunnelInfo.isEnabled = newValue
+ lock.unlock()
+ }
}
- }
- var protocolConfiguration: NEVPNProtocol? {
- get {
- lock.lock()
- defer { lock.unlock() }
+ var protocolConfiguration: NEVPNProtocol? {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
- return tunnelInfo.protocolConfiguration
+ return tunnelInfo.protocolConfiguration
+ }
+ set {
+ lock.lock()
+ tunnelInfo.protocolConfiguration = newValue
+ lock.unlock()
+ }
}
- set {
- lock.lock()
- tunnelInfo.protocolConfiguration = newValue
- lock.unlock()
+
+ var localizedDescription: String? {
+ get {
+ lock.lock()
+ defer { lock.unlock() }
+
+ return tunnelInfo.localizedDescription
+ }
+ set {
+ lock.lock()
+ tunnelInfo.localizedDescription = newValue
+ lock.unlock()
+ }
}
- }
- var localizedDescription: String? {
- get {
+ var connection: SimulatorVPNConnection {
lock.lock()
defer { lock.unlock() }
- return tunnelInfo.localizedDescription
- }
- set {
- lock.lock()
- tunnelInfo.localizedDescription = newValue
- lock.unlock()
+ return tunnelInfo.connection
}
- }
- var connection: SimulatorVPNConnection {
- lock.lock()
- defer { lock.unlock() }
+ static func loadAllFromPreferences(completionHandler: (
+ [SimulatorTunnelProviderManager]?,
+ Error?
+ ) -> Void) {
+ Self.tunnelsLock.lock()
+ let tunnelProviders = tunnels.map { tunnelInfo in
+ return SimulatorTunnelProviderManager(tunnelInfo: tunnelInfo)
+ }
+ Self.tunnelsLock.unlock()
- return tunnelInfo.connection
- }
+ completionHandler(tunnelProviders, nil)
+ }
- static func loadAllFromPreferences(completionHandler: ([SimulatorTunnelProviderManager]?, Error?) -> Void) {
- Self.tunnelsLock.lock()
- let tunnelProviders = tunnels.map { tunnelInfo in
- return SimulatorTunnelProviderManager(tunnelInfo: tunnelInfo)
+ required convenience init() {
+ self.init(tunnelInfo: SimulatorTunnelInfo())
}
- Self.tunnelsLock.unlock()
- completionHandler(tunnelProviders, nil)
- }
+ private init(tunnelInfo: SimulatorTunnelInfo) {
+ self.tunnelInfo = tunnelInfo
+ }
- required convenience init() {
- self.init(tunnelInfo: SimulatorTunnelInfo())
- }
+ func loadFromPreferences(completionHandler: (Error?) -> Void) {
+ var error: NEVPNError?
- private init(tunnelInfo: SimulatorTunnelInfo) {
- self.tunnelInfo = tunnelInfo
- }
+ Self.tunnelsLock.lock()
- func loadFromPreferences(completionHandler: (Error?) -> Void) {
- var error: NEVPNError?
+ if let savedTunnel = Self.tunnels.first(where: { $0.identifier == self.identifier }) {
+ tunnelInfo = savedTunnel
+ } else {
+ error = NEVPNError(.configurationInvalid)
+ }
- Self.tunnelsLock.lock()
+ Self.tunnelsLock.unlock()
- if let savedTunnel = Self.tunnels.first(where: { $0.identifier == self.identifier }) {
- self.tunnelInfo = savedTunnel
- } else {
- error = NEVPNError(.configurationInvalid)
+ completionHandler(error)
}
- Self.tunnelsLock.unlock()
+ func saveToPreferences(completionHandler: ((Error?) -> Void)?) {
+ Self.tunnelsLock.lock()
- completionHandler(error)
- }
+ if let index = Self.tunnels.firstIndex(where: { $0.identifier == self.identifier }) {
+ Self.tunnels[index] = tunnelInfo
+ } else {
+ Self.tunnels.append(tunnelInfo)
+ }
- func saveToPreferences(completionHandler: ((Error?) -> Void)?) {
- Self.tunnelsLock.lock()
+ Self.tunnelsLock.unlock()
- if let index = Self.tunnels.firstIndex(where: { $0.identifier == self.identifier }) {
- Self.tunnels[index] = self.tunnelInfo
- } else {
- Self.tunnels.append(self.tunnelInfo)
+ completionHandler?(nil)
}
- Self.tunnelsLock.unlock()
+ func removeFromPreferences(completionHandler: ((Error?) -> Void)?) {
+ var error: NEVPNError?
- completionHandler?(nil)
- }
+ Self.tunnelsLock.lock()
- func removeFromPreferences(completionHandler: ((Error?) -> Void)?) {
- var error: NEVPNError?
+ if let index = Self.tunnels.firstIndex(where: { $0.identifier == self.identifier }) {
+ Self.tunnels.remove(at: index)
+ } else {
+ error = NEVPNError(.configurationReadWriteFailed)
+ }
- Self.tunnelsLock.lock()
+ Self.tunnelsLock.unlock()
- if let index = Self.tunnels.firstIndex(where: { $0.identifier == self.identifier }) {
- Self.tunnels.remove(at: index)
- } else {
- error = NEVPNError(.configurationReadWriteFailed)
+ completionHandler?(error)
}
- Self.tunnelsLock.unlock()
-
- completionHandler?(error)
- }
-
- static func == (lhs: SimulatorTunnelProviderManager, rhs: SimulatorTunnelProviderManager) -> Bool {
- lhs.identifier == rhs.identifier
+ static func == (
+ lhs: SimulatorTunnelProviderManager,
+ rhs: SimulatorTunnelProviderManager
+ ) -> Bool {
+ lhs.identifier == rhs.identifier
+ }
}
-}
-
#endif
diff --git a/ios/MullvadVPN/SimulatorTunnelProviderHost.swift b/ios/MullvadVPN/SimulatorTunnelProviderHost.swift
index 7df234d75c..9c3b2623a7 100644
--- a/ios/MullvadVPN/SimulatorTunnelProviderHost.swift
+++ b/ios/MullvadVPN/SimulatorTunnelProviderHost.swift
@@ -8,104 +8,109 @@
#if targetEnvironment(simulator)
-import Foundation
-import enum NetworkExtension.NEProviderStopReason
-import Logging
+ import Foundation
+ import Logging
+ import enum NetworkExtension.NEProviderStopReason
-class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
- private var selectorResult: RelaySelectorResult?
+ class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
+ private var selectorResult: RelaySelectorResult?
- private let providerLogger = Logger(label: "SimulatorTunnelProviderHost")
- private let dispatchQueue = DispatchQueue(label: "SimulatorTunnelProviderHostQueue")
+ private let providerLogger = Logger(label: "SimulatorTunnelProviderHost")
+ private let dispatchQueue = DispatchQueue(label: "SimulatorTunnelProviderHostQueue")
- override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
- dispatchQueue.async {
- var selectorResult: RelaySelectorResult?
+ override func startTunnel(
+ options: [String: NSObject]?,
+ completionHandler: @escaping (Error?) -> Void
+ ) {
+ dispatchQueue.async {
+ var selectorResult: RelaySelectorResult?
- do {
- let tunnelOptions = PacketTunnelOptions(rawOptions: options ?? [:])
+ do {
+ let tunnelOptions = PacketTunnelOptions(rawOptions: options ?? [:])
- selectorResult = try tunnelOptions.getSelectorResult()
- } catch {
- self.providerLogger.error(
- chainedError: AnyChainedError(error),
- message: """
- Failed to decode relay selector result passed from the app. \
- Will continue by picking new relay.
- """
- )
- }
+ selectorResult = try tunnelOptions.getSelectorResult()
+ } catch {
+ self.providerLogger.error(
+ chainedError: AnyChainedError(error),
+ message: """
+ Failed to decode relay selector result passed from the app. \
+ Will continue by picking new relay.
+ """
+ )
+ }
- do {
- self.selectorResult = try selectorResult ?? self.pickRelay()
+ do {
+ self.selectorResult = try selectorResult ?? self.pickRelay()
- completionHandler(nil)
- } catch {
- self.providerLogger.error(
- chainedError: AnyChainedError(error),
- message: "Failed to pick relay."
- )
- completionHandler(error)
+ completionHandler(nil)
+ } catch {
+ self.providerLogger.error(
+ chainedError: AnyChainedError(error),
+ message: "Failed to pick relay."
+ )
+ completionHandler(error)
+ }
}
}
- }
- override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
- dispatchQueue.async {
- self.selectorResult = nil
+ override func stopTunnel(
+ with reason: NEProviderStopReason,
+ completionHandler: @escaping () -> Void
+ ) {
+ dispatchQueue.async {
+ self.selectorResult = nil
- completionHandler()
+ completionHandler()
+ }
}
- }
- override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
- dispatchQueue.async {
- do {
- let response = try self.processMessage(messageData)
+ override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
+ dispatchQueue.async {
+ do {
+ let response = try self.processMessage(messageData)
- completionHandler?(response)
- } catch {
- self.providerLogger.error(
- chainedError: AnyChainedError(error),
- message: "Failed to handle app message."
- )
+ completionHandler?(response)
+ } catch {
+ self.providerLogger.error(
+ chainedError: AnyChainedError(error),
+ message: "Failed to handle app message."
+ )
- completionHandler?(nil)
+ completionHandler?(nil)
+ }
}
}
- }
- private func processMessage(_ messageData: Data) throws -> Data? {
- let message = try TunnelProviderMessage(messageData: messageData)
+ private func processMessage(_ messageData: Data) throws -> Data? {
+ let message = try TunnelProviderMessage(messageData: messageData)
- switch message {
- case .getTunnelStatus:
- var tunnelStatus = PacketTunnelStatus()
- tunnelStatus.tunnelRelay = self.selectorResult?.packetTunnelRelay
+ switch message {
+ case .getTunnelStatus:
+ var tunnelStatus = PacketTunnelStatus()
+ tunnelStatus.tunnelRelay = self.selectorResult?.packetTunnelRelay
- return try TunnelProviderReply(tunnelStatus).encode()
+ return try TunnelProviderReply(tunnelStatus).encode()
- case .reconnectTunnel(let aSelectorResult):
- reasserting = true
- if let aSelectorResult = aSelectorResult {
- selectorResult = aSelectorResult
- }
- reasserting = false
+ case let .reconnectTunnel(aSelectorResult):
+ reasserting = true
+ if let aSelectorResult = aSelectorResult {
+ selectorResult = aSelectorResult
+ }
+ reasserting = false
- return nil
+ return nil
+ }
}
- }
- private func pickRelay() throws -> RelaySelectorResult {
- let cachedRelays = try RelayCache.Tracker.shared.getCachedRelays()
- let tunnelSettings = try SettingsManager.readSettings()
+ private func pickRelay() throws -> RelaySelectorResult {
+ let cachedRelays = try RelayCache.Tracker.shared.getCachedRelays()
+ let tunnelSettings = try SettingsManager.readSettings()
- return try RelaySelector.evaluate(
- relays: cachedRelays.relays,
- constraints: tunnelSettings.relayConstraints
- )
+ return try RelaySelector.evaluate(
+ relays: cachedRelays.relays,
+ constraints: tunnelSettings.relayConstraints
+ )
+ }
}
-}
-
#endif
diff --git a/ios/MullvadVPN/SpinnerActivityIndicatorView.swift b/ios/MullvadVPN/SpinnerActivityIndicatorView.swift
index 4c7332ae6f..f09cd507e7 100644
--- a/ios/MullvadVPN/SpinnerActivityIndicatorView.swift
+++ b/ios/MullvadVPN/SpinnerActivityIndicatorView.swift
@@ -121,7 +121,8 @@ class SpinnerActivityIndicatorView: UIView {
object: object,
queue: .main, using: { [weak self] _ in
self?.restartAnimationIfNeeded()
- })
+ }
+ )
}
private func unregisterSceneActivationObserver() {
@@ -134,7 +135,7 @@ class SpinnerActivityIndicatorView: UIView {
private func restartAnimationIfNeeded() {
let animation = layer.animation(forKey: Self.rotationAnimationKey)
- if isAnimating && animation == nil {
+ if isAnimating, animation == nil {
removeAnimation()
addAnimation()
}
diff --git a/ios/MullvadVPN/StatusImageView.swift b/ios/MullvadVPN/StatusImageView.swift
index 3507a833d3..af0ef14ae7 100644
--- a/ios/MullvadVPN/StatusImageView.swift
+++ b/ios/MullvadVPN/StatusImageView.swift
@@ -35,13 +35,13 @@ class StatusImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
- self.image = style.image
+ image = style.image
}
init(style: Style) {
self.style = style
super.init(image: style.image)
- self.image = style.image
+ image = style.image
}
required init?(coder: NSCoder) {
diff --git a/ios/MullvadVPN/String+Split.swift b/ios/MullvadVPN/String+Split.swift
index 82352280fc..f62317343b 100644
--- a/ios/MullvadVPN/String+Split.swift
+++ b/ios/MullvadVPN/String+Split.swift
@@ -9,7 +9,6 @@
import Foundation
extension String {
-
/// Returns the array of the longest possible subsequences of the given length.
func split(every length: Int) -> [Substring] {
guard length > 0 else { return [prefix(upTo: endIndex)] }
diff --git a/ios/MullvadVPN/Swizzle.swift b/ios/MullvadVPN/Swizzle.swift
index 994285ce56..6073384cf4 100644
--- a/ios/MullvadVPN/Swizzle.swift
+++ b/ios/MullvadVPN/Swizzle.swift
@@ -12,8 +12,18 @@ import Foundation
guard let originalMethod = class_getInstanceMethod(aClass, originalSelector),
let newMethod = class_getInstanceMethod(aClass, newSelector) else { return }
- if class_addMethod(aClass, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)) {
- class_replaceMethod(aClass, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
+ if class_addMethod(
+ aClass,
+ originalSelector,
+ method_getImplementation(newMethod),
+ method_getTypeEncoding(newMethod)
+ ) {
+ class_replaceMethod(
+ aClass,
+ newSelector,
+ method_getImplementation(originalMethod),
+ method_getTypeEncoding(originalMethod)
+ )
} else {
method_exchangeImplementations(originalMethod, newMethod)
}
diff --git a/ios/MullvadVPN/TermsOfServiceContentView.swift b/ios/MullvadVPN/TermsOfServiceContentView.swift
index 1f2740bbfb..58cf8b590e 100644
--- a/ios/MullvadVPN/TermsOfServiceContentView.swift
+++ b/ios/MullvadVPN/TermsOfServiceContentView.swift
@@ -9,7 +9,6 @@
import UIKit
class TermsOfServiceContentView: UIView {
-
let titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
@@ -133,24 +132,37 @@ class TermsOfServiceContentView: UIView {
footerContainer.bottomAnchor.constraint(equalTo: bottomAnchor),
agreeButton.topAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.topAnchor),
- agreeButton.leadingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
- agreeButton.trailingAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
- agreeButton.bottomAnchor.constraint(equalTo: footerContainer.layoutMarginsGuide.bottomAnchor),
+ agreeButton.leadingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.leadingAnchor),
+ agreeButton.trailingAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.trailingAnchor),
+ agreeButton.bottomAnchor
+ .constraint(equalTo: footerContainer.layoutMarginsGuide.bottomAnchor),
- titleLabel.topAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.topAnchor),
- titleLabel.leadingAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
- titleLabel.trailingAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.trailingAnchor),
+ titleLabel.topAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.topAnchor),
+ titleLabel.leadingAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
+ titleLabel.trailingAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.trailingAnchor),
bodyLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 24),
- bodyLabel.leadingAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
- bodyLabel.trailingAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.trailingAnchor),
+ bodyLabel.leadingAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
+ bodyLabel.trailingAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.trailingAnchor),
privacyPolicyLink.topAnchor.constraint(equalTo: bodyLabel.bottomAnchor, constant: 24),
- privacyPolicyLink.leadingAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
- privacyPolicyLink.trailingAnchor.constraint(lessThanOrEqualTo: scrollContentContainer.layoutMarginsGuide.trailingAnchor),
- privacyPolicyLink.bottomAnchor.constraint(equalTo: scrollContentContainer.layoutMarginsGuide.bottomAnchor),
+ privacyPolicyLink.leadingAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.leadingAnchor),
+ privacyPolicyLink.trailingAnchor
+ .constraint(
+ lessThanOrEqualTo: scrollContentContainer.layoutMarginsGuide
+ .trailingAnchor
+ ),
+ privacyPolicyLink.bottomAnchor
+ .constraint(equalTo: scrollContentContainer.layoutMarginsGuide.bottomAnchor),
])
}
-
}
diff --git a/ios/MullvadVPN/TermsOfServiceViewController.swift b/ios/MullvadVPN/TermsOfServiceViewController.swift
index dbc04555dc..3dd909fa06 100644
--- a/ios/MullvadVPN/TermsOfServiceViewController.swift
+++ b/ios/MullvadVPN/TermsOfServiceViewController.swift
@@ -9,8 +9,9 @@
import SafariServices
import UIKit
-class TermsOfServiceViewController: UIViewController, RootContainment, SFSafariViewControllerDelegate {
-
+class TermsOfServiceViewController: UIViewController, RootContainment,
+ SFSafariViewControllerDelegate
+{
var completionHandler: ((UIViewController) -> Void)?
override var preferredStatusBarStyle: UIStatusBarStyle {
@@ -32,8 +33,16 @@ class TermsOfServiceViewController: UIViewController, RootContainment, SFSafariV
let contentView = TermsOfServiceContentView()
contentView.translatesAutoresizingMaskIntoConstraints = false
- contentView.agreeButton.addTarget(self, action: #selector(handleAgreeButton(_:)), for: .touchUpInside)
- contentView.privacyPolicyLink.addTarget(self, action: #selector(handlePrivacyPolicyButton(_:)), for: .touchUpInside)
+ contentView.agreeButton.addTarget(
+ self,
+ action: #selector(handleAgreeButton(_:)),
+ for: .touchUpInside
+ )
+ contentView.privacyPolicyLink.addTarget(
+ self,
+ action: #selector(handlePrivacyPolicyButton(_:)),
+ for: .touchUpInside
+ )
view.backgroundColor = .primaryColor
view.addSubview(contentView)
@@ -49,7 +58,10 @@ class TermsOfServiceViewController: UIViewController, RootContainment, SFSafariV
// MARK: - Actions
@objc private func handlePrivacyPolicyButton(_ sender: Any) {
- let safariController = SFSafariViewController(url: ApplicationConfiguration.privacyPolicyURL)
+ let safariController = SFSafariViewController(
+ url: ApplicationConfiguration
+ .privacyPolicyURL
+ )
safariController.delegate = self
present(safariController, animated: true)
diff --git a/ios/MullvadVPN/TranslucentButtonBlurView.swift b/ios/MullvadVPN/TranslucentButtonBlurView.swift
index 78c916d5ec..d10e606baf 100644
--- a/ios/MullvadVPN/TranslucentButtonBlurView.swift
+++ b/ios/MullvadVPN/TranslucentButtonBlurView.swift
@@ -22,7 +22,7 @@ class TranslucentButtonBlurView: UIVisualEffectView {
button.topAnchor.constraint(equalTo: contentView.topAnchor),
button.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
button.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
- button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
+ button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
layer.cornerRadius = UIMetrics.controlCornerRadius
@@ -36,16 +36,20 @@ class TranslucentButtonBlurView: UIVisualEffectView {
}
private extension AppButton.Style {
- func cornerMask(_ userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection) -> CACornerMask {
+ func cornerMask(_ userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection)
+ -> CACornerMask
+ {
switch (self, userInterfaceLayoutDirection) {
- case (.translucentDangerSplitLeft, .leftToRight), (.translucentDangerSplitRight, .rightToLeft):
+ case (.translucentDangerSplitLeft, .leftToRight),
+ (.translucentDangerSplitRight, .rightToLeft):
return [.layerMinXMinYCorner, .layerMinXMaxYCorner]
- case (.translucentDangerSplitRight, .leftToRight), (.translucentDangerSplitLeft, .rightToLeft):
+ case (.translucentDangerSplitRight, .leftToRight),
+ (.translucentDangerSplitLeft, .rightToLeft):
return [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
default:
return [
.layerMinXMinYCorner, .layerMinXMaxYCorner,
- .layerMaxXMinYCorner, .layerMaxXMaxYCorner
+ .layerMaxXMinYCorner, .layerMaxXMaxYCorner,
]
}
}
diff --git a/ios/MullvadVPN/TunnelManager/LoadTunnelConfigurationOperation.swift b/ios/MullvadVPN/TunnelManager/LoadTunnelConfigurationOperation.swift
index 0fc5818d59..e98aaff5fd 100644
--- a/ios/MullvadVPN/TunnelManager/LoadTunnelConfigurationOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/LoadTunnelConfigurationOperation.swift
@@ -9,7 +9,7 @@
import Foundation
import Logging
-class LoadTunnelConfigurationOperation: ResultOperation<(), Error> {
+class LoadTunnelConfigurationOperation: ResultOperation<Void, Error> {
private let logger = Logger(label: "LoadTunnelConfigurationOperation")
private let interactor: TunnelInteractor
@@ -61,6 +61,7 @@ class LoadTunnelConfigurationOperation: ResultOperation<(), Error> {
finishOperation(tunnel: tunnel)
}
}
+
private func finishOperation(tunnel: Tunnel?) {
interactor.setTunnel(tunnel, shouldRefreshTunnelState: true)
interactor.setConfigurationLoaded()
diff --git a/ios/MullvadVPN/TunnelManager/LoadTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/LoadTunnelOperation.swift
index 7f9bec8515..39d474e38c 100644
--- a/ios/MullvadVPN/TunnelManager/LoadTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/LoadTunnelOperation.swift
@@ -9,13 +9,18 @@
import Foundation
import Logging
-class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
+class LoadTunnelOperation: ResultOperation<Void, TunnelManager.Error> {
private let accountToken: String?
private let state: TunnelManager.State
private let logger = Logger(label: "TunnelManager.LoadTunnelOperation")
- init(dispatchQueue: DispatchQueue, state: TunnelManager.State, accountToken: String?, completionHandler: @escaping CompletionHandler) {
+ init(
+ dispatchQueue: DispatchQueue,
+ state: TunnelManager.State,
+ accountToken: String?,
+ completionHandler: @escaping CompletionHandler
+ ) {
self.state = state
self.accountToken = accountToken
@@ -37,7 +42,7 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
if let accountToken = accountToken {
let migrationResult = migrateTunnelSettings(accountToken: accountToken)
- if case .failure(let migrationError) = migrationResult {
+ if case let .failure(migrationError) = migrationResult {
completionHandler(.failure(migrationError))
return
}
@@ -48,19 +53,29 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
if let error = error {
completionHandler(.failure(.loadAllVPNConfigurations(error)))
} else {
- self.didLoadVPNConfigurations(tunnels: tunnels, completionHandler: completionHandler)
+ self.didLoadVPNConfigurations(
+ tunnels: tunnels,
+ completionHandler: completionHandler
+ )
}
}
}
}
- private func didLoadVPNConfigurations(tunnels: [TunnelProviderManagerType]?, completionHandler: @escaping CompletionHandler) {
+ private func didLoadVPNConfigurations(
+ tunnels: [TunnelProviderManagerType]?,
+ completionHandler: @escaping CompletionHandler
+ ) {
if let tunnelProvider = tunnels?.first {
if let accountToken = accountToken {
// Case 1: tunnel exists and account token is set.
// Verify that tunnel can access the configuration via the persistent keychain reference
// stored in `passwordReference` field of VPN configuration.
- handleTunnelConsistency(tunnelProvider: tunnelProvider, accountToken: accountToken, completionHandler: completionHandler)
+ handleTunnelConsistency(
+ tunnelProvider: tunnelProvider,
+ accountToken: accountToken,
+ completionHandler: completionHandler
+ )
} else {
// Case 2: tunnel exists but account token is unset.
// Remove the orphaned tunnel.
@@ -78,10 +93,11 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
if let accountToken = accountToken {
// Case 3: tunnel does not exist but the account token is set.
// Verify that tunnel settings exists in keychain.
- let tunnelSettingsResult = TunnelSettingsManager.load(searchTerm: .accountToken(accountToken))
- .mapError { TunnelManager.Error.readTunnelSettings($0) }
+ let tunnelSettingsResult = TunnelSettingsManager
+ .load(searchTerm: .accountToken(accountToken))
+ .mapError { TunnelManager.Error.readTunnelSettings($0) }
- if case .success(let keychainEntry) = tunnelSettingsResult {
+ if case let .success(keychainEntry) = tunnelSettingsResult {
let tunnelInfo = TunnelInfo(
token: keychainEntry.accountToken,
tunnelSettings: keychainEntry.tunnelSettings
@@ -98,14 +114,25 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
}
}
- private func handleTunnelConsistency(tunnelProvider: TunnelProviderManagerType, accountToken: String, completionHandler: @escaping CompletionHandler) {
- let verificationResult = verifyTunnel(tunnelProvider: tunnelProvider, expectedAccountToken: accountToken)
- let tunnelSettingsResult = TunnelSettingsManager.load(searchTerm: .accountToken(accountToken))
+ private func handleTunnelConsistency(
+ tunnelProvider: TunnelProviderManagerType,
+ accountToken: String,
+ completionHandler: @escaping CompletionHandler
+ ) {
+ let verificationResult = verifyTunnel(
+ tunnelProvider: tunnelProvider,
+ expectedAccountToken: accountToken
+ )
+ let tunnelSettingsResult = TunnelSettingsManager
+ .load(searchTerm: .accountToken(accountToken))
.mapError { TunnelManager.Error.readTunnelSettings($0) }
switch (verificationResult, tunnelSettingsResult) {
- case (.success(true), .success(let keychainEntry)):
- let tunnelInfo = TunnelInfo(token: accountToken, tunnelSettings: keychainEntry.tunnelSettings)
+ case (.success(true), let .success(keychainEntry)):
+ let tunnelInfo = TunnelInfo(
+ token: accountToken,
+ tunnelSettings: keychainEntry.tunnelSettings
+ )
state.tunnelInfo = tunnelInfo
state.setTunnel(Tunnel(tunnelProvider: tunnelProvider), shouldRefreshTunnelState: true)
@@ -114,13 +141,16 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
// Remove the tunnel with corrupt configuration.
// It will be re-created upon the first attempt to connect the tunnel.
- case (.success(false), .success(let keychainEntry)):
+ case (.success(false), let .success(keychainEntry)):
tunnelProvider.removeFromPreferences { error in
self.dispatchQueue.async {
if let error = error {
completionHandler(.failure(.removeInconsistentVPNConfiguration(error)))
} else {
- let tunnelInfo = TunnelInfo(token: accountToken, tunnelSettings: keychainEntry.tunnelSettings)
+ let tunnelInfo = TunnelInfo(
+ token: accountToken,
+ tunnelSettings: keychainEntry.tunnelSettings
+ )
self.state.tunnelInfo = tunnelInfo
completionHandler(.success(()))
@@ -130,8 +160,11 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
// Remove the tunnel when failed to verify it but successfuly loaded the tunnel
// settings.
- case (.failure(let verificationError), .success(let keychainEntry)):
- logger.error(chainedError: verificationError, message: "Failed to verify the tunnel but successfully loaded the tunnel settings. Removing the tunnel.")
+ case let (.failure(verificationError), .success(keychainEntry)):
+ logger.error(
+ chainedError: verificationError,
+ message: "Failed to verify the tunnel but successfully loaded the tunnel settings. Removing the tunnel."
+ )
// Remove the tunnel with corrupt configuration.
// It will be re-created upon the first attempt to connect the tunnel.
@@ -140,7 +173,10 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
if let error = error {
completionHandler(.failure(.removeInconsistentVPNConfiguration(error)))
} else {
- let tunnelInfo = TunnelInfo(token: accountToken, tunnelSettings: keychainEntry.tunnelSettings)
+ let tunnelInfo = TunnelInfo(
+ token: accountToken,
+ tunnelSettings: keychainEntry.tunnelSettings
+ )
self.state.tunnelInfo = tunnelInfo
completionHandler(.success(()))
@@ -149,8 +185,11 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
}
// Remove the tunnel when failed to verify the tunnel and load tunnel settings.
- case (.failure(let verificationError), .failure(_)):
- logger.error(chainedError: verificationError, message: "Failed to verify the tunnel and load tunnel settings. Removing the tunnel.")
+ case let (.failure(verificationError), .failure(_)):
+ logger.error(
+ chainedError: verificationError,
+ message: "Failed to verify the tunnel and load tunnel settings. Removing the tunnel."
+ )
tunnelProvider.removeFromPreferences { error in
self.dispatchQueue.async {
@@ -163,8 +202,11 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
}
// Remove the tunnel when the app is not able to read tunnel settings
- case (.success(_), .failure(let settingsReadError)):
- logger.error(chainedError: settingsReadError, message: "Failed to load tunnel settings. Removing the tunnel.")
+ case let (.success(_), .failure(settingsReadError)):
+ logger.error(
+ chainedError: settingsReadError,
+ message: "Failed to load tunnel settings. Removing the tunnel."
+ )
tunnelProvider.removeFromPreferences { error in
self.dispatchQueue.async {
@@ -178,10 +220,18 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
}
}
- private func verifyTunnel(tunnelProvider: TunnelProviderManagerType, expectedAccountToken accountToken: String) -> Result<Bool, TunnelManager.Error> {
+ private func verifyTunnel(
+ tunnelProvider: TunnelProviderManagerType,
+ expectedAccountToken accountToken: String
+ ) -> Result<Bool, TunnelManager.Error> {
// Check that the VPN configuration points to the same account token
- guard let username = tunnelProvider.protocolConfiguration?.username, username == accountToken else {
- logger.warning("The token assigned to the VPN configuration does not match the logged in account.")
+ guard let username = tunnelProvider.protocolConfiguration?.username,
+ username == accountToken
+ else {
+ logger
+ .warning(
+ "The token assigned to the VPN configuration does not match the logged in account."
+ )
return .success(false)
}
@@ -195,8 +245,11 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
// Verify that the keychain reference points to the existing entry in Keychain.
// Bad reference is possible when migrating the user data from one device to the other.
return TunnelSettingsManager.exists(searchTerm: .persistentReference(keychainReference))
- .mapError { (error) -> TunnelManager.Error in
- logger.error(chainedError: error, message: "Failed to verify the persistent keychain reference for tunnel settings.")
+ .mapError { error -> TunnelManager.Error in
+ logger.error(
+ chainedError: error,
+ message: "Failed to verify the persistent keychain reference for tunnel settings."
+ )
return .readTunnelSettings(error)
}
@@ -205,19 +258,19 @@ class LoadTunnelOperation: ResultOperation<(), TunnelManager.Error> {
private func migrateTunnelSettings(accountToken: String) -> Result<Bool, TunnelManager.Error> {
let result = TunnelSettingsManager
.migrateKeychainEntry(searchTerm: .accountToken(accountToken))
- .mapError { (error) -> TunnelManager.Error in
+ .mapError { error -> TunnelManager.Error in
return .migrateTunnelSettings(error)
}
switch result {
- case .success(let migrated):
+ case let .success(migrated):
if migrated {
logger.info("Migrated Keychain tunnel configuration.")
} else {
logger.info("Tunnel settings are up to date. No migration needed.")
}
- case .failure(let error):
+ case let .failure(error):
logger.error(chainedError: error)
}
diff --git a/ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift b/ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift
index 873968521b..c34e2fc8c0 100644
--- a/ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import NetworkExtension
import Logging
+import NetworkExtension
class MapConnectionStatusOperation: AsyncOperation {
private let interactor: TunnelInteractor
@@ -21,8 +21,7 @@ class MapConnectionStatusOperation: AsyncOperation {
queue: DispatchQueue,
interactor: TunnelInteractor,
connectionStatus: NEVPNStatus
- )
- {
+ ) {
self.interactor = interactor
self.connectionStatus = connectionStatus
@@ -103,13 +102,12 @@ class MapConnectionStatusOperation: AsyncOperation {
private func updateTunnelRelayAndFinish(
tunnel: Tunnel,
mapRelayToState: @escaping (PacketTunnelRelay?) -> TunnelState?
- )
- {
+ ) {
request = tunnel.getTunnelStatus { [weak self] completion in
guard let self = self else { return }
self.dispatchQueue.async {
- if case .success(let packetTunnelStatus) = completion, !self.isCancelled {
+ if case let .success(packetTunnelStatus) = completion, !self.isCancelled {
self.interactor.updateTunnelStatus(
from: packetTunnelStatus,
mappingRelayToState: mapRelayToState
diff --git a/ios/MullvadVPN/TunnelManager/MigrateSettingsOperation.swift b/ios/MullvadVPN/TunnelManager/MigrateSettingsOperation.swift
index d67f8e37e8..17fc69cff1 100644
--- a/ios/MullvadVPN/TunnelManager/MigrateSettingsOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/MigrateSettingsOperation.swift
@@ -29,8 +29,7 @@ class MigrateSettingsOperation: AsyncOperation {
dispatchQueue: DispatchQueue,
accountsProxy: REST.AccountsProxy,
devicesProxy: REST.DevicesProxy
- )
- {
+ ) {
self.accountsProxy = accountsProxy
self.devicesProxy = devicesProxy
@@ -139,12 +138,15 @@ class MigrateSettingsOperation: AsyncOperation {
}
}
- private func didFinishAccountRequest(_ completion: OperationCompletion<REST.AccountData, REST.Error>) {
+ private func didFinishAccountRequest(_ completion: OperationCompletion<
+ REST.AccountData,
+ REST.Error
+ >) {
switch completion {
- case .success(let accountData):
+ case let .success(accountData):
self.accountData = accountData
- case .failure(let error):
+ case let .failure(error):
logger.error(chainedError: error, message: "Failed to fetch accound data.")
case .cancelled:
@@ -152,12 +154,15 @@ class MigrateSettingsOperation: AsyncOperation {
}
}
- private func didFinishDeviceRequest(_ completion: OperationCompletion<[REST.Device], REST.Error>) {
+ private func didFinishDeviceRequest(_ completion: OperationCompletion<
+ [REST.Device],
+ REST.Error
+ >) {
switch completion {
- case .success(let devices):
+ case let .success(devices):
self.devices = devices
- case .failure(let error):
+ case let .failure(error):
logger.error(chainedError: error, message: "Failed to fetch devices.")
case .cancelled:
@@ -176,7 +181,7 @@ class MigrateSettingsOperation: AsyncOperation {
// Find device that matches the public key stored in legacy settings.
let device = devices.first { device in
return device.pubkey == interfaceData.privateKey.publicKey ||
- device.pubkey == interfaceData.nextPrivateKey?.publicKey
+ device.pubkey == interfaceData.nextPrivateKey?.publicKey
}
guard let device = device else {
@@ -190,8 +195,7 @@ class MigrateSettingsOperation: AsyncOperation {
// Match private key.
let privateKeyWithMetadata: PrivateKeyWithMetadata
- if let nextKey = interfaceData.nextPrivateKey, nextKey.publicKey == device.pubkey
- {
+ if let nextKey = interfaceData.nextPrivateKey, nextKey.publicKey == device.pubkey {
privateKeyWithMetadata = nextKey
} else {
privateKeyWithMetadata = interfaceData.privateKey
@@ -249,5 +253,4 @@ class MigrateSettingsOperation: AsyncOperation {
finish()
}
-
}
diff --git a/ios/MullvadVPN/TunnelManager/PacketTunnelOptions.swift b/ios/MullvadVPN/TunnelManager/PacketTunnelOptions.swift
index ca8b0ecb50..d6a3578bc5 100644
--- a/ios/MullvadVPN/TunnelManager/PacketTunnelOptions.swift
+++ b/ios/MullvadVPN/TunnelManager/PacketTunnelOptions.swift
@@ -9,7 +9,6 @@
import Foundation
struct PacketTunnelOptions {
-
/// Keys for options dictionary
private enum Keys: String {
/// Option key that holds the `NSData` value with `RelaySelectorResult` encoded using `JSONEncoder`.
diff --git a/ios/MullvadVPN/TunnelManager/PacketTunnelStatus.swift b/ios/MullvadVPN/TunnelManager/PacketTunnelStatus.swift
index c7ffbb2191..9283e37cb8 100644
--- a/ios/MullvadVPN/TunnelManager/PacketTunnelStatus.swift
+++ b/ios/MullvadVPN/TunnelManager/PacketTunnelStatus.swift
@@ -11,7 +11,7 @@ import Foundation
/// Struct describing packet tunnel process status.
struct PacketTunnelStatus: Codable, Equatable {
/// Flag indicating whether network is reachable.
- var isNetworkReachable: Bool = true
+ var isNetworkReachable = true
/// When the packet tunnel started connecting.
var connectingDate: Date?
diff --git a/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
index e48d17482a..495e5f0479 100644
--- a/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
@@ -8,7 +8,7 @@
import Foundation
-class ReconnectTunnelOperation: ResultOperation<(), Error> {
+class ReconnectTunnelOperation: ResultOperation<Void, Error> {
private let interactor: TunnelInteractor
private let selectNewRelay: Bool
private var task: Cancellable?
@@ -17,8 +17,7 @@ class ReconnectTunnelOperation: ResultOperation<(), Error> {
dispatchQueue: DispatchQueue,
interactor: TunnelInteractor,
selectNewRelay: Bool
- )
- {
+ ) {
self.interactor = interactor
self.selectNewRelay = selectNewRelay
diff --git a/ios/MullvadVPN/TunnelManager/RegenerateTunnelPrivateKeyOperation.swift b/ios/MullvadVPN/TunnelManager/RegenerateTunnelPrivateKeyOperation.swift
index 8d26fa6b05..14c7245908 100644
--- a/ios/MullvadVPN/TunnelManager/RegenerateTunnelPrivateKeyOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/RegenerateTunnelPrivateKeyOperation.swift
@@ -9,7 +9,7 @@
import Foundation
class RegeneratePrivateKeyOperation: AsyncOperation {
- typealias CompletionHandler = (OperationCompletion<(), TunnelManager.Error>) -> Void
+ typealias CompletionHandler = (OperationCompletion<Void, TunnelManager.Error>) -> Void
private let queue: DispatchQueue
private let state: TunnelManager.State
@@ -17,7 +17,12 @@ class RegeneratePrivateKeyOperation: AsyncOperation {
private var completionHandler: CompletionHandler?
private var restRequest: Cancellable?
- init(queue: DispatchQueue, state: TunnelManager.State, restClient: REST.Client, completionHandler: @escaping CompletionHandler) {
+ init(
+ queue: DispatchQueue,
+ state: TunnelManager.State,
+ restClient: REST.Client,
+ completionHandler: @escaping CompletionHandler
+ ) {
self.queue = queue
self.state = state
self.restClient = restClient
@@ -46,7 +51,7 @@ class RegeneratePrivateKeyOperation: AsyncOperation {
}
private func execute(completionHandler: @escaping CompletionHandler) {
- guard !self.isCancelled else {
+ guard !isCancelled else {
completionHandler(.cancelled)
return
}
@@ -59,7 +64,7 @@ class RegeneratePrivateKeyOperation: AsyncOperation {
let newPrivateKey = PrivateKeyWithMetadata()
let oldPublicKey = tunnelInfo.tunnelSettings.interface.publicKey
- let restRequestAdapter = self.restClient.replaceWireguardKey(
+ let restRequestAdapter = restClient.replaceWireguardKey(
token: tunnelInfo.token,
oldPublicKey: oldPublicKey,
newPublicKey: newPrivateKey.publicKey
@@ -67,9 +72,13 @@ class RegeneratePrivateKeyOperation: AsyncOperation {
restRequest = restRequestAdapter.execute(retryStrategy: .default) { restResult in
self.queue.async {
- let saveResult = Self.handleResponse(accountToken: tunnelInfo.token, newPrivateKey: newPrivateKey, result: restResult)
+ let saveResult = Self.handleResponse(
+ accountToken: tunnelInfo.token,
+ newPrivateKey: newPrivateKey,
+ result: restResult
+ )
- if case .success(let newTunnelSettings) = saveResult {
+ if case let .success(newTunnelSettings) = saveResult {
self.state.tunnelInfo?.tunnelSettings = newTunnelSettings
}
@@ -78,21 +87,25 @@ class RegeneratePrivateKeyOperation: AsyncOperation {
}
}
- private class func handleResponse(accountToken: String, newPrivateKey: PrivateKeyWithMetadata, result: Result<REST.WireguardAddressesResponse, REST.Error>) -> Result<TunnelSettings, TunnelManager.Error> {
+ private class func handleResponse(
+ accountToken: String,
+ newPrivateKey: PrivateKeyWithMetadata,
+ result: Result<REST.WireguardAddressesResponse, REST.Error>
+ ) -> Result<TunnelSettings, TunnelManager.Error> {
return result.flatMapError { restError in
return .failure(.replaceWireguardKey(restError))
}
.flatMap { associatedAddresses in
- return TunnelSettingsManager.update(searchTerm: .accountToken(accountToken)) { newTunnelSettings in
- newTunnelSettings.interface.privateKey = newPrivateKey
- newTunnelSettings.interface.addresses = [
- associatedAddresses.ipv4Address,
- associatedAddresses.ipv6Address
- ]
- }.mapError { error -> TunnelManager.Error in
- return .updateTunnelSettings(error)
- }
+ return TunnelSettingsManager
+ .update(searchTerm: .accountToken(accountToken)) { newTunnelSettings in
+ newTunnelSettings.interface.privateKey = newPrivateKey
+ newTunnelSettings.interface.addresses = [
+ associatedAddresses.ipv4Address,
+ associatedAddresses.ipv6Address,
+ ]
+ }.mapError { error -> TunnelManager.Error in
+ return .updateTunnelSettings(error)
+ }
}
}
-
}
diff --git a/ios/MullvadVPN/TunnelManager/RotateKeyOperation.swift b/ios/MullvadVPN/TunnelManager/RotateKeyOperation.swift
index ae5470b75e..5cdf10a872 100644
--- a/ios/MullvadVPN/TunnelManager/RotateKeyOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/RotateKeyOperation.swift
@@ -37,7 +37,7 @@ class RotateKeyOperation: ResultOperation<Bool, Error> {
}
override func main() {
- guard case .loggedIn(let accountData, let deviceData) = interactor.deviceState else {
+ guard case let .loggedIn(accountData, deviceData) = interactor.deviceState else {
finish(completion: .failure(InvalidDeviceStateError()))
return
}
@@ -85,10 +85,9 @@ class RotateKeyOperation: ResultOperation<Bool, Error> {
private func didRotateKey(
newPrivateKey: PrivateKey,
completion: OperationCompletion<REST.Device, REST.Error>
- )
- {
+ ) {
switch completion {
- case .success(let device):
+ case let .success(device):
logger.debug("Successfully rotated device key. Persisting settings...")
switch interactor.deviceState {
@@ -106,7 +105,7 @@ class RotateKeyOperation: ResultOperation<Bool, Error> {
finish(completion: .failure(InvalidDeviceStateError()))
}
- case .failure(let error):
+ case let .failure(error):
logger.error(
chainedError: AnyChainedError(error),
message: "Failed to rotate device key."
@@ -116,6 +115,5 @@ class RotateKeyOperation: ResultOperation<Bool, Error> {
case .cancelled:
finish(completion: .cancelled)
}
-
}
}
diff --git a/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift b/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift
index 85227c5874..2652433cee 100644
--- a/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift
@@ -101,7 +101,7 @@ final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output,
}
private func handleVPNStatus(_ status: NEVPNStatus) {
- guard !isCancelled && !messageSent else {
+ guard !isCancelled, !messageSent else {
return
}
@@ -201,8 +201,7 @@ extension SendTunnelProviderMessageOperation where Output: Codable {
tunnel: Tunnel,
message: TunnelProviderMessage,
completionHandler: @escaping CompletionHandler
- )
- {
+ ) {
self.init(
dispatchQueue: dispatchQueue,
tunnel: tunnel,
@@ -248,7 +247,7 @@ enum SendTunnelProviderMessageError: ChainedError {
var errorDescription: String? {
switch self {
- case .tunnelDown(let status):
+ case let .tunnelDown(status):
return "Tunnel is either down or about to go down (status: \(status))."
case .timeout:
return "Send timeout."
diff --git a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
index 022264489d..12d7f9b3a5 100644
--- a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
@@ -7,9 +7,9 @@
//
import Foundation
-import class WireGuardKitTypes.PublicKey
-import class WireGuardKitTypes.PrivateKey
import Logging
+import class WireGuardKitTypes.PrivateKey
+import class WireGuardKitTypes.PublicKey
enum SetAccountAction {
/// Set new account.
@@ -47,9 +47,10 @@ private struct SetAccountContext: OperationInputContext {
func reduce() -> SetAccountResult? {
guard let accountData = accountData,
let privateKey = privateKey,
- let device = device else {
- return nil
- }
+ let device = device
+ else {
+ return nil
+ }
return SetAccountResult(
accountData: accountData,
@@ -76,8 +77,7 @@ class SetAccountOperation: ResultOperation<StoredAccountData?, Error> {
accountsProxy: REST.AccountsProxy,
devicesProxy: REST.DevicesProxy,
action: SetAccountAction
- )
- {
+ ) {
self.interactor = interactor
self.accountsProxy = accountsProxy
self.devicesProxy = devicesProxy
@@ -88,7 +88,7 @@ class SetAccountOperation: ResultOperation<StoredAccountData?, Error> {
override func main() {
var deleteDeviceOperation: AsyncOperation?
- if case .loggedIn(let accountData, let deviceData) = interactor.deviceState {
+ if case let .loggedIn(accountData, deviceData) = interactor.deviceState {
let operation = getDeleteDeviceOperation(
accounNumber: accountData.number,
deviceIdentifier: deviceData.identifier
@@ -187,7 +187,7 @@ class SetAccountOperation: ResultOperation<StoredAccountData?, Error> {
case .new:
return getCreateAccountOperation()
- case .existing(let accountNumber):
+ case let .existing(accountNumber):
return getExistingAccountOperation(accountNumber: accountNumber)
case .unset:
diff --git a/ios/MullvadVPN/TunnelManager/SetTunnelSettingsOperation.swift b/ios/MullvadVPN/TunnelManager/SetTunnelSettingsOperation.swift
index d1761a215a..28c0731a4c 100644
--- a/ios/MullvadVPN/TunnelManager/SetTunnelSettingsOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/SetTunnelSettingsOperation.swift
@@ -8,13 +8,18 @@
import Foundation
-class SetTunnelSettingsOperation: ResultOperation<(), TunnelManager.Error> {
+class SetTunnelSettingsOperation: ResultOperation<Void, TunnelManager.Error> {
typealias ModificationHandler = (inout TunnelSettings) -> Void
private let state: TunnelManager.State
private let modificationBlock: ModificationHandler
- init(dispatchQueue: DispatchQueue, state: TunnelManager.State, modificationBlock: @escaping ModificationHandler, completionHandler: @escaping CompletionHandler) {
+ init(
+ dispatchQueue: DispatchQueue,
+ state: TunnelManager.State,
+ modificationBlock: @escaping ModificationHandler,
+ completionHandler: @escaping CompletionHandler
+ ) {
self.state = state
self.modificationBlock = modificationBlock
@@ -31,16 +36,17 @@ class SetTunnelSettingsOperation: ResultOperation<(), TunnelManager.Error> {
return
}
- let result = TunnelSettingsManager.update(searchTerm: .accountToken(accountToken)) { tunnelSettings in
- modificationBlock(&tunnelSettings)
- }
+ let result = TunnelSettingsManager
+ .update(searchTerm: .accountToken(accountToken)) { tunnelSettings in
+ modificationBlock(&tunnelSettings)
+ }
switch result {
- case .success(let newTunnelSettings):
+ case let .success(newTunnelSettings):
state.tunnelInfo?.tunnelSettings = newTunnelSettings
finish(completion: .success(()))
- case .failure(let error):
+ case let .failure(error):
finish(completion: .failure(.updateTunnelSettings(error)))
}
}
diff --git a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
index cb3a738490..f30867bc97 100644
--- a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
@@ -7,10 +7,10 @@
//
import Foundation
-import NetworkExtension
import Logging
+import NetworkExtension
-class StartTunnelOperation: ResultOperation<(), Error> {
+class StartTunnelOperation: ResultOperation<Void, Error> {
typealias EncodeErrorHandler = (Error) -> Void
private let interactor: TunnelInteractor
@@ -20,8 +20,7 @@ class StartTunnelOperation: ResultOperation<(), Error> {
dispatchQueue: DispatchQueue,
interactor: TunnelInteractor,
completionHandler: @escaping CompletionHandler
- )
- {
+ ) {
self.interactor = interactor
super.init(
@@ -100,13 +99,21 @@ class StartTunnelOperation: ResultOperation<(), Error> {
)
}
- interactor.setTunnel(Tunnel(tunnelProvider: tunnelProvider), shouldRefreshTunnelState: false)
+ interactor.setTunnel(
+ Tunnel(tunnelProvider: tunnelProvider),
+ shouldRefreshTunnelState: false
+ )
interactor.resetTunnelState(to: .connecting(selectorResult.packetTunnelRelay))
try tunnelProvider.connection.startVPNTunnel(options: tunnelOptions.rawOptions())
}
- private class func makeTunnelProvider(completionHandler: @escaping (Result<TunnelProviderManagerType, Error>) -> Void) {
+ private class func makeTunnelProvider(
+ completionHandler: @escaping (Result<
+ TunnelProviderManagerType,
+ Error
+ >) -> Void
+ ) {
TunnelProviderManagerType.loadAllFromPreferences { tunnelProviders, error in
if let error = error {
completionHandler(.failure(error))
@@ -135,7 +142,8 @@ class StartTunnelOperation: ResultOperation<(), Error> {
private class func configureTunnelProvider(_ tunnelProvider: TunnelProviderManagerType) {
let protocolConfig = NETunnelProviderProtocol()
- protocolConfig.providerBundleIdentifier = ApplicationConfiguration.packetTunnelExtensionIdentifier
+ protocolConfig.providerBundleIdentifier = ApplicationConfiguration
+ .packetTunnelExtensionIdentifier
protocolConfig.serverAddress = ""
tunnelProvider.isEnabled = true
diff --git a/ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift
index bd0501f114..00814f024b 100644
--- a/ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift
@@ -8,15 +8,14 @@
import Foundation
-class StopTunnelOperation: ResultOperation<(), Error> {
+class StopTunnelOperation: ResultOperation<Void, Error> {
private let interactor: TunnelInteractor
init(
dispatchQueue: DispatchQueue,
interactor: TunnelInteractor,
completionHandler: @escaping CompletionHandler
- )
- {
+ ) {
self.interactor = interactor
super.init(
diff --git a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
index b773a54b1a..ef737466f3 100644
--- a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
+++ b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
@@ -36,8 +36,7 @@ extension Tunnel {
/// Request status from packet tunnel process.
func getTunnelStatus(
completionHandler: @escaping (OperationCompletion<PacketTunnelStatus, Error>) -> Void
- ) -> Cancellable
- {
+ ) -> Cancellable {
let operation = SendTunnelProviderMessageOperation(
dispatchQueue: dispatchQueue,
tunnel: self,
diff --git a/ios/MullvadVPN/TunnelManager/Tunnel.swift b/ios/MullvadVPN/TunnelManager/Tunnel.swift
index 93477eb403..682b969485 100644
--- a/ios/MullvadVPN/TunnelManager/Tunnel.swift
+++ b/ios/MullvadVPN/TunnelManager/Tunnel.swift
@@ -11,9 +11,9 @@ import NetworkExtension
// Switch to stabs on simulator
#if targetEnvironment(simulator)
-typealias TunnelProviderManagerType = SimulatorTunnelProviderManager
+ typealias TunnelProviderManagerType = SimulatorTunnelProviderManager
#else
-typealias TunnelProviderManagerType = NETunnelProviderManager
+ typealias TunnelProviderManagerType = NETunnelProviderManager
#endif
protocol TunnelStatusObserver {
@@ -23,7 +23,7 @@ protocol TunnelStatusObserver {
/// Tunnel wrapper class.
class Tunnel {
/// Tunnel provider manager.
- fileprivate let tunnelProvider: TunnelProviderManagerType
+ private let tunnelProvider: TunnelProviderManagerType
/// Tunnel start date.
///
@@ -90,7 +90,10 @@ class Tunnel {
tunnelProvider.removeFromPreferences(completionHandler: completion)
}
- func addBlockObserver(queue: DispatchQueue? = nil, handler: @escaping (Tunnel, NEVPNStatus) -> Void) -> TunnelStatusBlockObserver {
+ func addBlockObserver(
+ queue: DispatchQueue? = nil,
+ handler: @escaping (Tunnel, NEVPNStatus) -> Void
+ ) -> TunnelStatusBlockObserver {
let observer = TunnelStatusBlockObserver(tunnel: self, queue: queue, handler: handler)
addObserver(observer)
diff --git a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
index b3d2b7b495..b2f19523b0 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
@@ -9,7 +9,6 @@
import Foundation
protocol TunnelInteractor {
-
// MARK: - Tunnel manipulation
var tunnel: Tunnel? { get }
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
index f42a60b84f..2014a90cc0 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
@@ -7,10 +7,10 @@
//
import Foundation
+import Logging
import NetworkExtension
-import UIKit
import StoreKit
-import Logging
+import UIKit
import class WireGuardKitTypes.PublicKey
enum TunnelManagerConfiguration {
@@ -50,12 +50,10 @@ final class TunnelManager {
}
}
- static let shared: TunnelManager = {
- return TunnelManager(
- accountsProxy: REST.ProxyFactory.shared.createAccountsProxy(),
- devicesProxy: REST.ProxyFactory.shared.createDevicesProxy()
- )
- }()
+ static let shared = TunnelManager(
+ accountsProxy: REST.ProxyFactory.shared.createAccountsProxy(),
+ devicesProxy: REST.ProxyFactory.shared.createDevicesProxy()
+ )
// MARK: - Internal variables
@@ -130,7 +128,7 @@ final class TunnelManager {
nslock.lock()
defer { nslock.unlock() }
- guard case .loggedIn(_, let deviceData) = deviceState else {
+ guard case let .loggedIn(_, deviceData) = deviceState else {
return nil
}
@@ -142,7 +140,8 @@ final class TunnelManager {
// Do not rotate the key if account or device is not found.
if let restError = completion.error as? REST.Error,
restError.compareErrorCode(.invalidAccount) ||
- restError.compareErrorCode(.deviceNotFound) {
+ restError.compareErrorCode(.deviceNotFound)
+ {
return nil
}
@@ -203,7 +202,6 @@ final class TunnelManager {
lastKeyRotationData = nil
updatePrivateKeyRotationTimer()
-
}
// MARK: - Public methods
@@ -223,7 +221,7 @@ final class TunnelManager {
loadTunnelOperation.completionHandler = { [weak self] completion in
guard let self = self else { return }
- if case .failure(let error) = completion {
+ if case let .failure(error) = completion {
self.logger.error(
chainedError: AnyChainedError(error),
message: "Failed to load configuration."
@@ -237,7 +235,7 @@ final class TunnelManager {
loadTunnelOperation.addDependency(migrateSettingsOperation)
let groupOperation = GroupOperation(operations: [
- migrateSettingsOperation, loadTunnelOperation
+ migrateSettingsOperation, loadTunnelOperation,
])
groupOperation.addObserver(
@@ -262,7 +260,7 @@ final class TunnelManager {
_refreshTunnelStatus()
}
- func startTunnel(completionHandler: ((OperationCompletion<(), Error>) -> Void)? = nil) {
+ func startTunnel(completionHandler: ((OperationCompletion<Void, Error>) -> Void)? = nil) {
let operation = StartTunnelOperation(
dispatchQueue: internalQueue,
interactor: TunnelInteractorProxy(self),
@@ -285,7 +283,8 @@ final class TunnelManager {
completionHandler?(completion)
}
- })
+ }
+ )
operation.addObserver(BackgroundObserver(name: "Start tunnel", cancelUponExpiration: true))
operation.addCondition(MutuallyExclusive(category: OperationCategory.manageTunnel.category))
@@ -293,7 +292,7 @@ final class TunnelManager {
operationQueue.addOperation(operation)
}
- func stopTunnel(completionHandler: ((OperationCompletion<(), Error>) -> Void)? = nil) {
+ func stopTunnel(completionHandler: ((OperationCompletion<Void, Error>) -> Void)? = nil) {
let operation = StopTunnelOperation(
dispatchQueue: internalQueue,
interactor: TunnelInteractorProxy(self)
@@ -326,9 +325,8 @@ final class TunnelManager {
func reconnectTunnel(
selectNewRelay: Bool,
- completionHandler: ((OperationCompletion<(), Error>) -> Void)? = nil
- )
- {
+ completionHandler: ((OperationCompletion<Void, Error>) -> Void)? = nil
+ ) {
let operation = ReconnectTunnelOperation(
dispatchQueue: internalQueue,
interactor: TunnelInteractorProxy(self),
@@ -352,7 +350,10 @@ final class TunnelManager {
operationQueue.addOperation(operation)
}
- func setAccount(action: SetAccountAction, completionHandler: @escaping (OperationCompletion<StoredAccountData?, Error>) -> Void) {
+ func setAccount(
+ action: SetAccountAction,
+ completionHandler: @escaping (OperationCompletion<StoredAccountData?, Error>) -> Void
+ ) {
let operation = SetAccountOperation(
dispatchQueue: internalQueue,
interactor: TunnelInteractorProxy(self),
@@ -412,7 +413,10 @@ final class TunnelManager {
operationQueue.addOperation(operation)
}
- func updateDeviceData(_ completionHandler: @escaping (OperationCompletion<StoredDeviceData, Error>) -> Void) -> Cancellable {
+ func updateDeviceData(_ completionHandler: @escaping (OperationCompletion<
+ StoredDeviceData,
+ Error
+ >) -> Void) -> Cancellable {
let operation = UpdateDeviceDataOperation(
dispatchQueue: internalQueue,
interactor: TunnelInteractorProxy(self),
@@ -471,7 +475,7 @@ final class TunnelManager {
completionHandler(completion)
}
- case .failure(let error):
+ case let .failure(error):
self.checkIfDeviceRevoked(error)
completionHandler(.failure(error))
@@ -494,7 +498,10 @@ final class TunnelManager {
return operation
}
- func setRelayConstraints(_ newConstraints: RelayConstraints, completionHandler: (() -> Void)? = nil) {
+ func setRelayConstraints(
+ _ newConstraints: RelayConstraints,
+ completionHandler: (() -> Void)? = nil
+ ) {
scheduleSettingsUpdate(
taskName: "Set relay constraints",
modificationBlock: { settings in
@@ -613,8 +620,7 @@ final class TunnelManager {
fileprivate func updateTunnelStatus(
from packetTunnelStatus: PacketTunnelStatus,
mappingRelayToState mapper: (PacketTunnelRelay?) -> TunnelState?
- )
- {
+ ) {
nslock.lock()
defer { nslock.unlock() }
@@ -654,7 +660,7 @@ final class TunnelManager {
}
DispatchQueue.main.async {
- self.observerList.forEach { (observer) in
+ self.observerList.forEach { observer in
observer.tunnelManager(self, didUpdateTunnelState: newTunnelStatus.state)
}
}
@@ -746,7 +752,7 @@ final class TunnelManager {
)
}
- private func didReconnectTunnel(completion: OperationCompletion<(), Error>) {
+ private func didReconnectTunnel(completion: OperationCompletion<Void, Error>) {
nslock.lock()
defer { nslock.unlock() }
@@ -776,12 +782,13 @@ final class TunnelManager {
unsubscribeVPNStatusObserver()
- statusObserver = tunnel.addBlockObserver(queue: internalQueue) { [weak self] tunnel, status in
- guard let self = self else { return }
+ statusObserver = tunnel
+ .addBlockObserver(queue: internalQueue) { [weak self] tunnel, status in
+ guard let self = self else { return }
- self.logger.debug("VPN connection status changed to \(status).")
- self.updateTunnelStatus(status)
- }
+ self.logger.debug("VPN connection status changed to \(status).")
+ self.updateTunnelStatus(status)
+ }
}
private func unsubscribeVPNStatusObserver() {
@@ -829,8 +836,7 @@ final class TunnelManager {
taskName: String,
modificationBlock: @escaping (inout TunnelSettingsV2) -> Void,
completionHandler: (() -> Void)?
- )
- {
+ ) {
let operation = AsyncBlockOperation(dispatchQueue: internalQueue) {
let currentSettings = self._tunnelSettings
var updatedSettings = self._tunnelSettings
@@ -864,8 +870,7 @@ final class TunnelManager {
taskName: String,
modificationBlock: @escaping (inout DeviceState) -> Void,
completionHandler: (() -> Void)?
- )
- {
+ ) {
let operation = AsyncBlockOperation(dispatchQueue: internalQueue) {
var deviceState = self.deviceState
@@ -891,7 +896,9 @@ final class TunnelManager {
// MARK: - Tunnel status polling
- private func computeNextPollDateAndRepeatInterval(connectingDate: Date?) -> (Date, TimeInterval) {
+ private func computeNextPollDateAndRepeatInterval(connectingDate: Date?)
+ -> (Date, TimeInterval)
+ {
let delay, repeating: TimeInterval
let fireDate: Date
@@ -929,8 +936,14 @@ final class TunnelManager {
lastConnectingDate = connectingDate
isPolling = true
- let (fireDate, repeating) = computeNextPollDateAndRepeatInterval(connectingDate: connectingDate)
- logger.debug("Start polling tunnel status at \(fireDate.logFormatDate()) every \(repeating) second(s).")
+ let (
+ fireDate,
+ repeating
+ ) = computeNextPollDateAndRepeatInterval(connectingDate: connectingDate)
+ logger
+ .debug(
+ "Start polling tunnel status at \(fireDate.logFormatDate()) every \(repeating) second(s)."
+ )
let timer = DispatchSource.makeTimerSource(queue: .main)
timer.setEventHandler { [weak self] in
@@ -961,7 +974,6 @@ final class TunnelManager {
lastConnectingDate = nil
isPolling = false
}
-
}
// MARK: - AppStore payment observer
@@ -973,8 +985,7 @@ extension TunnelManager: AppStorePaymentObserver {
payment: SKPayment,
accountToken: String?,
didFailWithError error: AppStorePaymentManager.Error
- )
- {
+ ) {
// no-op
}
@@ -983,8 +994,7 @@ extension TunnelManager: AppStorePaymentObserver {
transaction: SKPaymentTransaction,
accountToken: String,
didFinishWithResponse response: REST.CreateApplePaymentResponse
- )
- {
+ ) {
scheduleDeviceStateUpdate(
taskName: "Update account expiry after in-app purchase",
modificationBlock: { deviceState in
@@ -1030,8 +1040,7 @@ private struct TunnelInteractorProxy: TunnelInteractor {
func updateTunnelStatus(
from packetTunnelStatus: PacketTunnelStatus,
mappingRelayToState mapper: (PacketTunnelRelay?) -> TunnelState?
- )
- {
+ ) {
tunnelManager.updateTunnelStatus(from: packetTunnelStatus, mappingRelayToState: mapper)
}
@@ -1074,5 +1083,4 @@ private struct TunnelInteractorProxy: TunnelInteractor {
func prepareForVPNConfigurationDeletion() {
tunnelManager.prepareForVPNConfigurationDeletion()
}
-
}
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManagerState.swift b/ios/MullvadVPN/TunnelManager/TunnelManagerState.swift
index c777052c39..2e82f59018 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManagerState.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManagerState.swift
@@ -10,7 +10,6 @@ import Foundation
import NetworkExtension
protocol TunnelManagerStateDelegate: AnyObject {
-
func tunnelManagerState(
_ state: TunnelManager.State,
didChangeLoadedConfiguration isLoadedConfiguration: Bool
@@ -34,7 +33,6 @@ protocol TunnelManagerStateDelegate: AnyObject {
}
extension TunnelManager {
-
class State {
weak var delegate: TunnelManagerStateDelegate?
let delegateQueue: DispatchQueue
diff --git a/ios/MullvadVPN/TunnelManager/TunnelState.swift b/ios/MullvadVPN/TunnelManager/TunnelState.swift
index bfbc0da3e9..fc06f1cd0d 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelState.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelState.swift
@@ -33,7 +33,10 @@ struct TunnelStatus: Equatable, CustomStringConvertible {
}
/// Updates the tunnel status from packet tunnel status, mapping relay to tunnel state.
- mutating func update(from packetTunnelStatus: PacketTunnelStatus, mappingRelayToState mapper: (PacketTunnelRelay?) -> TunnelState?) {
+ mutating func update(
+ from packetTunnelStatus: PacketTunnelStatus,
+ mappingRelayToState mapper: (PacketTunnelRelay?) -> TunnelState?
+ ) {
self.packetTunnelStatus = packetTunnelStatus
if let newState = mapper(packetTunnelStatus.tunnelRelay) {
@@ -75,19 +78,19 @@ enum TunnelState: Equatable, CustomStringConvertible {
switch self {
case .pendingReconnect:
return "pending reconnect after disconnect"
- case .connecting(let tunnelRelay):
+ case let .connecting(tunnelRelay):
if let tunnelRelay = tunnelRelay {
return "connecting to \(tunnelRelay.hostname)"
} else {
return "connecting, fetching relay"
}
- case .connected(let tunnelRelay):
+ case let .connected(tunnelRelay):
return "connected to \(tunnelRelay.hostname)"
- case .disconnecting(let actionAfterDisconnect):
+ case let .disconnecting(actionAfterDisconnect):
return "disconnecting and then \(actionAfterDisconnect)"
case .disconnected:
return "disconnected"
- case .reconnecting(let tunnelRelay):
+ case let .reconnecting(tunnelRelay):
return "reconnecting to \(tunnelRelay.hostname)"
}
}
diff --git a/ios/MullvadVPN/TunnelManager/UpdateAccountDataOperation.swift b/ios/MullvadVPN/TunnelManager/UpdateAccountDataOperation.swift
index 25669631c5..d0f62c68e4 100644
--- a/ios/MullvadVPN/TunnelManager/UpdateAccountDataOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/UpdateAccountDataOperation.swift
@@ -19,8 +19,7 @@ class UpdateAccountDataOperation: ResultOperation<Void, Error> {
dispatchQueue: DispatchQueue,
interactor: TunnelInteractor,
accountsProxy: REST.AccountsProxy
- )
- {
+ ) {
self.interactor = interactor
self.accountsProxy = accountsProxy
@@ -28,7 +27,7 @@ class UpdateAccountDataOperation: ResultOperation<Void, Error> {
}
override func main() {
- guard case .loggedIn(let accountData, _) = interactor.deviceState else {
+ guard case let .loggedIn(accountData, _) = interactor.deviceState else {
finish(completion: .failure(InvalidDeviceStateError()))
return
}
diff --git a/ios/MullvadVPN/TunnelManager/UpdateDeviceDataOperation.swift b/ios/MullvadVPN/TunnelManager/UpdateDeviceDataOperation.swift
index af20dbc2a1..da7bc3d7bd 100644
--- a/ios/MullvadVPN/TunnelManager/UpdateDeviceDataOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/UpdateDeviceDataOperation.swift
@@ -20,8 +20,7 @@ class UpdateDeviceDataOperation: ResultOperation<StoredDeviceData, Error> {
dispatchQueue: DispatchQueue,
interactor: TunnelInteractor,
devicesProxy: REST.DevicesProxy
- )
- {
+ ) {
self.interactor = interactor
self.devicesProxy = devicesProxy
@@ -29,7 +28,7 @@ class UpdateDeviceDataOperation: ResultOperation<StoredDeviceData, Error> {
}
override func main() {
- guard case .loggedIn(let accountData, let deviceData) = interactor.deviceState else {
+ guard case let .loggedIn(accountData, deviceData) = interactor.deviceState else {
finish(completion: .failure(InvalidDeviceStateError()))
return
}
@@ -44,7 +43,8 @@ class UpdateDeviceDataOperation: ResultOperation<StoredDeviceData, Error> {
completion: completion
)
}
- })
+ }
+ )
}
override func operationDidCancel() {
@@ -71,5 +71,4 @@ class UpdateDeviceDataOperation: ResultOperation<StoredDeviceData, Error> {
finish(completion: mappedCompletion)
}
-
}
diff --git a/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift b/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift
index ee81308440..f42e7a2f7b 100644
--- a/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift
+++ b/ios/MullvadVPN/UIBarButtonItem+KeyboardNavigation.swift
@@ -9,7 +9,6 @@
import UIKit
extension UIBarButtonItem {
-
enum KeyboardNavigationItemType {
case previous, next
@@ -43,18 +42,43 @@ extension UIBarButtonItem {
}
}
- convenience init(keyboardNavigationItemType: KeyboardNavigationItemType, target: Any?, action: Selector?) {
+ convenience init(
+ keyboardNavigationItemType: KeyboardNavigationItemType,
+ target: Any?,
+ action: Selector?
+ ) {
if #available(iOS 13, *) {
- self.init(image: keyboardNavigationItemType.systemImage, style: .plain, target: target, action: action)
+ 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(
+ title: keyboardNavigationItemType.localizedTitle,
+ style: .plain,
+ target: target,
+ action: action
+ )
}
accessibilityLabel = keyboardNavigationItemType.localizedTitle
}
- static func makeKeyboardNavigationItems(_ configurationBlock: (_ prevItem: UIBarButtonItem, _ nextItem: UIBarButtonItem) -> Void) -> [UIBarButtonItem] {
- let prevButton = UIBarButtonItem(keyboardNavigationItemType: .previous, target: nil, action: nil)
- let nextButton = UIBarButtonItem(keyboardNavigationItemType: .next, target: nil, action: nil)
+ static func makeKeyboardNavigationItems(_ configurationBlock: (
+ _ prevItem: UIBarButtonItem,
+ _ nextItem: UIBarButtonItem
+ ) -> Void) -> [UIBarButtonItem] {
+ let prevButton = UIBarButtonItem(
+ keyboardNavigationItemType: .previous,
+ target: nil,
+ action: nil
+ )
+ let nextButton = UIBarButtonItem(
+ keyboardNavigationItemType: .next,
+ target: nil,
+ action: nil
+ )
configurationBlock(prevButton, nextButton)
@@ -67,5 +91,4 @@ extension UIBarButtonItem {
return [prevButton, nextButton]
}
}
-
}
diff --git a/ios/MullvadVPN/UIColor+Helpers.swift b/ios/MullvadVPN/UIColor+Helpers.swift
index 08f36a32ac..a119f64660 100644
--- a/ios/MullvadVPN/UIColor+Helpers.swift
+++ b/ios/MullvadVPN/UIColor+Helpers.swift
@@ -9,7 +9,6 @@
import UIKit
extension UIColor {
-
/// Returns the color lighter by the given percent (in range from 0..1)
func lightened(by percent: CGFloat) -> UIColor? {
return darkened(by: -percent)
@@ -21,15 +20,16 @@ extension UIColor {
let factor = 1.0 - percent
if getRed(&r, green: &g, blue: &b, alpha: &a) {
- return UIColor(red: clampColorComponent(r * factor),
- green: clampColorComponent(g * factor),
- blue: clampColorComponent(b * factor),
- alpha: a)
+ return UIColor(
+ red: clampColorComponent(r * factor),
+ green: clampColorComponent(g * factor),
+ blue: clampColorComponent(b * factor),
+ alpha: a
+ )
}
return nil
}
-
}
private func clampColorComponent(_ value: CGFloat) -> CGFloat {
diff --git a/ios/MullvadVPN/UIColor+Palette.swift b/ios/MullvadVPN/UIColor+Palette.swift
index dcb8c98e45..0617868656 100644
--- a/ios/MullvadVPN/UIColor+Palette.swift
+++ b/ios/MullvadVPN/UIColor+Palette.swift
@@ -9,7 +9,6 @@
import UIKit
extension UIColor {
-
enum AccountTextField {
enum NormalState {
static let borderColor = secondaryColor
diff --git a/ios/MullvadVPN/UIFont+Monospaced.swift b/ios/MullvadVPN/UIFont+Monospaced.swift
index 5ce7bb633b..0690070e01 100644
--- a/ios/MullvadVPN/UIFont+Monospaced.swift
+++ b/ios/MullvadVPN/UIFont+Monospaced.swift
@@ -17,8 +17,8 @@ extension UIFont {
let fontDescriptor = UIFontDescriptor(fontAttributes: [
.name: "Menlo",
.traits: [
- UIFontDescriptor.TraitKey.weight: weight
- ]
+ UIFontDescriptor.TraitKey.weight: weight,
+ ],
])
return UIFont(descriptor: fontDescriptor, size: size)
diff --git a/ios/MullvadVPN/UIImage+TintColor.swift b/ios/MullvadVPN/UIImage+TintColor.swift
index b8b7dd1731..46fd6326bf 100644
--- a/ios/MullvadVPN/UIImage+TintColor.swift
+++ b/ios/MullvadVPN/UIImage+TintColor.swift
@@ -9,7 +9,6 @@
import UIKit
extension UIImage {
-
func backport_withTintColor(_ tintColor: UIColor) -> UIImage {
return backport_withTintColor(tintColor, renderingMode: renderingMode)
}
@@ -30,5 +29,4 @@ extension UIImage {
return renderedImage.withRenderingMode(renderingMode)
}
-
}
diff --git a/ios/MullvadVPN/UIMetrics.swift b/ios/MullvadVPN/UIMetrics.swift
index db45331197..1e9ee912c1 100644
--- a/ios/MullvadVPN/UIMetrics.swift
+++ b/ios/MullvadVPN/UIMetrics.swift
@@ -11,7 +11,6 @@ import UIKit
enum UIMetrics {}
extension UIMetrics {
-
/// Common layout margins for content presentation
static let contentLayoutMargins = UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
@@ -23,13 +22,23 @@ extension UIMetrics {
static let settingsCellLayoutMargins = UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 12)
/// Common layout margins for location cell presentation
- static let selectLocationCellLayoutMargins = UIEdgeInsets(top: 16, left: 28, bottom: 16, right: 12)
+ static let selectLocationCellLayoutMargins = UIEdgeInsets(
+ top: 16,
+ left: 28,
+ bottom: 16,
+ right: 12
+ )
/// Common cell indentation width
static let cellIndentationWidth: CGFloat = 16
/// Layout margins for in-app notification banner presentation
- static let inAppBannerNotificationLayoutMargins = UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 24)
+ static let inAppBannerNotificationLayoutMargins = UIEdgeInsets(
+ top: 16,
+ left: 24,
+ bottom: 16,
+ right: 24
+ )
/// Spacing used in stack views of buttons
static let interButtonSpacing: CGFloat = 16
@@ -51,5 +60,4 @@ extension UIMetrics {
/// Maximum sidebar width in percentage points (0...1)
static let maximumSplitViewSidebarWidthFraction: CGFloat = 0.3
-
}
diff --git a/ios/MullvadVPN/UserInterfaceInteractionRestriction.swift b/ios/MullvadVPN/UserInterfaceInteractionRestriction.swift
index 2a07132c09..ca5e63dfce 100644
--- a/ios/MullvadVPN/UserInterfaceInteractionRestriction.swift
+++ b/ios/MullvadVPN/UserInterfaceInteractionRestriction.swift
@@ -18,8 +18,7 @@ protocol UserInterfaceInteractionRestrictionProtocol {
}
/// A counter based user interface interaction restriction implementation
-class UserInterfaceInteractionRestriction: UserInterfaceInteractionRestrictionProtocol
-{
+class UserInterfaceInteractionRestriction: UserInterfaceInteractionRestrictionProtocol {
typealias Action = (_ enableUserInteraction: Bool, _ animated: Bool) -> Void
private let action: Action
diff --git a/ios/MullvadVPN/WireguardKeysContentView.swift b/ios/MullvadVPN/WireguardKeysContentView.swift
index 4086047974..cc978bd218 100644
--- a/ios/MullvadVPN/WireguardKeysContentView.swift
+++ b/ios/MullvadVPN/WireguardKeysContentView.swift
@@ -9,7 +9,6 @@
import UIKit
class WireguardKeysContentView: UIView {
-
let regenerateKeyButton: AppButton = {
let button = AppButton(style: .success)
button.translatesAutoresizingMaskIntoConstraints = false
@@ -81,10 +80,13 @@ class WireguardKeysContentView: UIView {
contentStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
contentStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonStackView.topAnchor.constraint(greaterThanOrEqualTo: contentStackView.bottomAnchor, constant: UIMetrics.sectionSpacing),
+ buttonStackView.topAnchor.constraint(
+ greaterThanOrEqualTo: contentStackView.bottomAnchor,
+ constant: UIMetrics.sectionSpacing
+ ),
buttonStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
buttonStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ buttonStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
])
}
@@ -94,7 +96,6 @@ class WireguardKeysContentView: UIView {
}
class WireguardKeysPublicKeyRow: UIView {
-
var value: String? {
didSet {
valueButton.setTitle(value, for: .normal)
@@ -159,7 +160,10 @@ class WireguardKeysPublicKeyRow: UIView {
NSLayoutConstraint.activate([
textLabel.topAnchor.constraint(equalTo: topAnchor),
textLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
- textLabel.trailingAnchor.constraint(greaterThanOrEqualTo: statusView.leadingAnchor, constant: -8),
+ textLabel.trailingAnchor.constraint(
+ greaterThanOrEqualTo: statusView.leadingAnchor,
+ constant: -8
+ ),
statusView.topAnchor.constraint(equalTo: textLabel.topAnchor),
statusView.bottomAnchor.constraint(equalTo: textLabel.bottomAnchor),
@@ -168,7 +172,7 @@ class WireguardKeysPublicKeyRow: UIView {
valueButton.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 8),
valueButton.leadingAnchor.constraint(equalTo: leadingAnchor),
valueButton.trailingAnchor.constraint(equalTo: trailingAnchor),
- valueButton.bottomAnchor.constraint(equalTo: bottomAnchor)
+ valueButton.bottomAnchor.constraint(equalTo: bottomAnchor),
])
isAccessibilityElement = true
@@ -185,7 +189,7 @@ class WireguardKeysPublicKeyRow: UIView {
name: actionName,
target: self,
selector: #selector(performAccessibilityAction)
- )
+ ),
]
valueButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
@@ -196,9 +200,9 @@ class WireguardKeysPublicKeyRow: UIView {
}
private func updateAccessibilityLabel() {
- var accessibilityLabelString = self.textLabel.text ?? ""
+ var accessibilityLabelString = textLabel.text ?? ""
- if case .verified(let isValid) = status {
+ if case let .verified(isValid) = status {
accessibilityLabelString += ", "
if isValid {
@@ -230,12 +234,11 @@ class WireguardKeysPublicKeyRow: UIView {
}
@objc private func performAccessibilityAction() {
- self.actionHandler?()
+ actionHandler?()
}
}
class WireguardKeysCreationRow: UIView {
-
var value: String? {
didSet {
accessibilityValue = value
@@ -279,7 +282,7 @@ class WireguardKeysCreationRow: UIView {
valueLabel.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 8),
valueLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
valueLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
- valueLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
+ valueLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
])
isAccessibilityElement = true
@@ -335,7 +338,7 @@ class WireguardKeyStatusView: UIView {
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
- stackView.trailingAnchor.constraint(equalTo: trailingAnchor)
+ stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
])
updateView()
@@ -354,7 +357,7 @@ class WireguardKeyStatusView: UIView {
case .regenerating, .verifying:
startSpinner()
- case .verified(let isValid):
+ case let .verified(isValid):
textLabel.isHidden = false
activityIndicator.stopAnimating()
@@ -382,5 +385,4 @@ class WireguardKeyStatusView: UIView {
textLabel.isHidden = true
activityIndicator.startAnimating()
}
-
}
diff --git a/ios/MullvadVPN/WireguardKeysViewController.swift b/ios/MullvadVPN/WireguardKeysViewController.swift
index a177519483..0a5f751058 100644
--- a/ios/MullvadVPN/WireguardKeysViewController.swift
+++ b/ios/MullvadVPN/WireguardKeysViewController.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import UIKit
import Logging
+import UIKit
/// A UI refresh interval for the public key creation date (in seconds)
private let creationDateRefreshInterval = Int(60)
@@ -25,7 +25,6 @@ private enum WireguardKeysViewState {
}
class WireguardKeysViewController: UIViewController, TunnelObserver {
-
private let contentView: WireguardKeysContentView = {
let contentView = WireguardKeysContentView()
contentView.translatesAutoresizingMaskIntoConstraints = false
@@ -64,7 +63,8 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
- contentView.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.bottomAnchor),
+ contentView.bottomAnchor
+ .constraint(greaterThanOrEqualTo: scrollView.safeAreaLayoutGuide.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
@@ -81,8 +81,16 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
self?.copyPublicKey()
}
- contentView.regenerateKeyButton.addTarget(self, action: #selector(handleRegenerateKey(_:)), for: .touchUpInside)
- contentView.verifyKeyButton.addTarget(self, action: #selector(handleVerifyKey(_:)), for: .touchUpInside)
+ contentView.regenerateKeyButton.addTarget(
+ self,
+ action: #selector(handleRegenerateKey(_:)),
+ for: .touchUpInside
+ )
+ contentView.verifyKeyButton.addTarget(
+ self,
+ action: #selector(handleVerifyKey(_:)),
+ for: .touchUpInside
+ )
TunnelManager.shared.addObserver(self)
updatePublicKey(deviceData: TunnelManager.shared.deviceState.deviceData, animated: false)
@@ -93,13 +101,16 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
private func startPublicKeyPeriodicUpdate() {
let interval = DispatchTimeInterval.seconds(creationDateRefreshInterval)
let timerSource = DispatchSource.makeTimerSource(queue: .main)
- timerSource.setEventHandler { [weak self] () -> Void in
- self?.updatePublicKey(deviceData: TunnelManager.shared.deviceState.deviceData, animated: true)
+ timerSource.setEventHandler { [weak self] () in
+ self?.updatePublicKey(
+ deviceData: TunnelManager.shared.deviceState.deviceData,
+ animated: true
+ )
}
timerSource.schedule(deadline: .now() + interval, repeating: interval)
timerSource.activate()
- self.publicKeyPeriodicUpdateTimer = timerSource
+ publicKeyPeriodicUpdateTimer = timerSource
}
// MARK: - TunnelObserver
@@ -112,8 +123,11 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
// no-op
}
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2) {
- // no-op
+ func tunnelManager(
+ _ manager: TunnelManager,
+ didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
+ ) {
+ // no-op
}
func tunnelManager(_ manager: TunnelManager, didUpdateDeviceState deviceState: DeviceState) {
@@ -138,7 +152,8 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
value: "COPIED TO PASTEBOARD!",
comment: ""
),
- animated: true)
+ animated: true
+ )
let workItem = DispatchWorkItem { [weak self] in
self?.updatePublicKey(
@@ -167,7 +182,7 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
from: creationDate,
to: Date(),
unitsStyle: .full
- ).map { (formattedInterval) -> String in
+ ).map { formattedInterval -> String in
return String(
format: NSLocalizedString(
"KEY_GENERATED_SINCE_FORMAT",
@@ -181,7 +196,8 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
}
private func updateCreationDateLabel(with creationDate: Date) {
- contentView.creationRowView.value = formatKeyGenerationElapsedTime(with: creationDate) ?? "-"
+ contentView.creationRowView
+ .value = formatKeyGenerationElapsedTime(with: creationDate) ?? "-"
}
private func updatePublicKey(deviceData: StoredDeviceData?, animated: Bool) {
@@ -210,7 +226,7 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
setKeyActionButtonsEnabled(false)
contentView.publicKeyRowView.status = .verifying
- case .verifiedKey(let isValid):
+ case let .verifiedKey(isValid):
setKeyActionButtonsEnabled(true)
contentView.publicKeyRowView.status = .verified(isValid)
announceKeyVerificationResult(isValid: isValid)
@@ -219,13 +235,12 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
setKeyActionButtonsEnabled(false)
contentView.publicKeyRowView.status = .regenerating
- case .regeneratedKey(let success):
+ case let .regeneratedKey(success):
setKeyActionButtonsEnabled(true)
contentView.publicKeyRowView.status = .default
if success {
announceKeyRegenerated()
}
-
}
}
@@ -246,9 +261,10 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
case .success:
self.updateViewState(.verifiedKey(true))
- case .failure(let error):
+ case let .failure(error):
if let restError = error as? REST.Error,
- restError.compareErrorCode(.deviceNotFound) {
+ restError.compareErrorCode(.deviceNotFound)
+ {
self.updateViewState(.verifiedKey(false))
} else {
self.showKeyVerificationFailureAlert(error)
@@ -262,7 +278,7 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
}
private func regeneratePrivateKey() {
- self.updateViewState(.regeneratingKey)
+ updateViewState(.regeneratingKey)
_ = TunnelManager.shared.rotatePrivateKey(forceRotate: true) { [weak self] completion in
guard let self = self else { return }
@@ -271,9 +287,10 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
case .success:
self.updateViewState(.regeneratedKey(true))
- case .failure(let error):
+ case let .failure(error):
if let restError = error as? REST.Error,
- restError.compareErrorCode(.deviceNotFound) {
+ restError.compareErrorCode(.deviceNotFound)
+ {
self.updateViewState(.regeneratedKey(false))
} else {
self.showKeyRegenerationFailureAlert(error)
@@ -349,7 +366,6 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
alertPresenter.enqueue(alertController, presentingController: self)
}
-
private func setPublicKeyTitle(string: String, animated: Bool) {
let updateTitle = {
self.contentView.publicKeyRowView.value = string
@@ -396,5 +412,4 @@ class WireguardKeysViewController: UIViewController, TunnelObserver {
)
UIAccessibility.post(notification: .announcement, argument: announcementString)
}
-
}
diff --git a/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift b/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift
index ab39539c3f..7cf720c959 100644
--- a/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift
+++ b/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift
@@ -9,7 +9,6 @@
import XCTest
class MullvadVPNScreenshots: XCTestCase {
-
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
diff --git a/ios/MullvadVPNTests/AccountTokenInputTests.swift b/ios/MullvadVPNTests/AccountTokenInputTests.swift
index 75dd39f4bf..c7a0d2ccd5 100644
--- a/ios/MullvadVPNTests/AccountTokenInputTests.swift
+++ b/ios/MullvadVPNTests/AccountTokenInputTests.swift
@@ -11,7 +11,6 @@ import XCTest
private let kSampleToken = "12345678"
class AccountTokenInputTests: XCTestCase {
-
func testInitialValue() {
let input = AccountTokenInput(string: kSampleToken)
@@ -33,7 +32,8 @@ class AccountTokenInputTests: XCTestCase {
input.replaceCharacters(
in: input.formattedString.range(withOffset: 4, length: 1),
replacementString: "",
- emptySelection: true)
+ emptySelection: true
+ )
XCTAssertEqual(input.formattedString, "1235 678")
XCTAssertEqual(input.caretPosition, 3)
@@ -45,7 +45,8 @@ class AccountTokenInputTests: XCTestCase {
input.replaceCharacters(
in: input.formattedString.range(withOffset: 4, length: 1),
replacementString: "",
- emptySelection: false)
+ emptySelection: false
+ )
XCTAssertEqual(input.formattedString, "1234 5678")
XCTAssertEqual(input.caretPosition, 4)
@@ -57,7 +58,8 @@ class AccountTokenInputTests: XCTestCase {
input.replaceCharacters(
in: input.formattedString.range(withOffset: 7, length: 2),
replacementString: "",
- emptySelection: false)
+ emptySelection: false
+ )
XCTAssertEqual(input.formattedString, "1234 56")
XCTAssertEqual(input.caretPosition, 7)
@@ -69,7 +71,8 @@ class AccountTokenInputTests: XCTestCase {
input.replaceCharacters(
in: input.formattedString.range(withOffset: 5, length: 0),
replacementString: "0000",
- emptySelection: true)
+ emptySelection: true
+ )
XCTAssertEqual(input.formattedString, "1234 0000 5678")
XCTAssertEqual(input.caretPosition, 9)
@@ -81,12 +84,12 @@ class AccountTokenInputTests: XCTestCase {
input.replaceCharacters(
in: input.formattedString.range(withOffset: 5, length: 4),
replacementString: "0000",
- emptySelection: false)
+ emptySelection: false
+ )
XCTAssertEqual(input.formattedString, "1234 0000")
XCTAssertEqual(input.caretPosition, 9)
}
-
}
private extension String {
diff --git a/ios/MullvadVPNTests/CustomDateComponentsFormattingTests.swift b/ios/MullvadVPNTests/CustomDateComponentsFormattingTests.swift
index f2fdf623d0..a4301c68d1 100644
--- a/ios/MullvadVPNTests/CustomDateComponentsFormattingTests.swift
+++ b/ios/MullvadVPNTests/CustomDateComponentsFormattingTests.swift
@@ -9,7 +9,6 @@
import XCTest
class CustomDateComponentsFormattingTests: XCTestCase {
-
func testCloseToOneDayFormatting() throws {
var dateComponents = DateComponents()
dateComponents.hour = 23
@@ -20,7 +19,7 @@ class CustomDateComponentsFormattingTests: XCTestCase {
let result = CustomDateComponentsFormatting.localizedString(
from: startDate,
to: endDate,
- calendar: self.calendar,
+ calendar: calendar,
unitsStyle: .full
)
@@ -36,7 +35,7 @@ class CustomDateComponentsFormattingTests: XCTestCase {
let result = CustomDateComponentsFormatting.localizedString(
from: startDate,
to: endDate,
- calendar: self.calendar,
+ calendar: calendar,
unitsStyle: .full
)
@@ -55,5 +54,4 @@ class CustomDateComponentsFormattingTests: XCTestCase {
calendar.locale = Locale(identifier: "en_US_POSIX")
return calendar
}
-
}
diff --git a/ios/MullvadVPNTests/DataSourceSnapshotTests.swift b/ios/MullvadVPNTests/DataSourceSnapshotTests.swift
index 1d626e1688..4587df4a75 100644
--- a/ios/MullvadVPNTests/DataSourceSnapshotTests.swift
+++ b/ios/MullvadVPNTests/DataSourceSnapshotTests.swift
@@ -9,7 +9,6 @@
import XCTest
class DataSourceSnapshotTests: XCTestCase {
-
func testInsertingItem() throws {
var a = DataSourceSnapshot<String, Int>()
var b = DataSourceSnapshot<String, Int>()
@@ -65,7 +64,7 @@ class DataSourceSnapshotTests: XCTestCase {
a.appendSections(["First", "Second"])
b.appendSections(["First", "Second"])
- a.appendItems([1, 2, 3 ,4], in: "First")
+ a.appendItems([1, 2, 3, 4], in: "First")
a.appendItems([5, 6, 7, 8], in: "Second")
b.appendItems([5, 1, 2, 8, 4], in: "First")
@@ -76,13 +75,13 @@ class DataSourceSnapshotTests: XCTestCase {
XCTAssertEqual(diff.indexPathsToDelete, [
IndexPath(row: 3, section: 1),
IndexPath(row: 0, section: 1),
- IndexPath(row: 2, section: 0)
+ IndexPath(row: 2, section: 0),
])
XCTAssertEqual(diff.indexPathsToInsert, [
IndexPath(row: 0, section: 0),
IndexPath(row: 3, section: 0),
- IndexPath(row: 1, section: 1)
+ IndexPath(row: 1, section: 1),
])
}
@@ -100,12 +99,12 @@ class DataSourceSnapshotTests: XCTestCase {
XCTAssertEqual(diff.indexPathsToDelete, [
IndexPath(row: 2, section: 0),
- IndexPath(row: 0, section: 0)
+ IndexPath(row: 0, section: 0),
])
XCTAssertEqual(diff.indexPathsToInsert, [
IndexPath(row: 0, section: 0),
- IndexPath(row: 2, section: 0)
+ IndexPath(row: 2, section: 0),
])
}
@@ -143,5 +142,4 @@ class DataSourceSnapshotTests: XCTestCase {
XCTAssertEqual(diff.indexPathsToReload, [IndexPath(row: 0, section: 0)])
XCTAssertEqual(diff.indexPathsToReconfigure, [IndexPath(row: 1, section: 0)])
}
-
}
diff --git a/ios/MullvadVPNTests/OperationConditionTests.swift b/ios/MullvadVPNTests/OperationConditionTests.swift
index 297b8128ee..80bf13b2da 100644
--- a/ios/MullvadVPNTests/OperationConditionTests.swift
+++ b/ios/MullvadVPNTests/OperationConditionTests.swift
@@ -77,7 +77,7 @@ class OperationConditionTests: XCTestCase {
let expectToNeverExecute = expectation(description: "Expect child to never execute.")
expectToNeverExecute.isInverted = true
- let parent = ResultBlockOperation<(), URLError> {
+ let parent = ResultBlockOperation<Void, URLError> {
throw URLError(.badURL)
}
@@ -140,5 +140,4 @@ class OperationConditionTests: XCTestCase {
let expectations = [expectFirstOperationExecution, expectSecondOperationExecution]
wait(for: expectations, timeout: 2, enforceOrder: true)
}
-
}
diff --git a/ios/MullvadVPNTests/OperationInputInjectionTests.swift b/ios/MullvadVPNTests/OperationInputInjectionTests.swift
index d62214af42..52394f89f1 100644
--- a/ios/MullvadVPNTests/OperationInputInjectionTests.swift
+++ b/ios/MullvadVPNTests/OperationInputInjectionTests.swift
@@ -9,7 +9,6 @@
import XCTest
class OperationInputInjectionTests: XCTestCase {
-
func testInject() throws {
let provider = ResultBlockOperation<Int, Error> {
return 1
@@ -86,5 +85,4 @@ class OperationInputInjectionTests: XCTestCase {
XCTAssertEqual(consumer.output, "3")
}
-
}
diff --git a/ios/MullvadVPNTests/OperationObserverTests.swift b/ios/MullvadVPNTests/OperationObserverTests.swift
index bc1c92b442..5c9d257fdc 100644
--- a/ios/MullvadVPNTests/OperationObserverTests.swift
+++ b/ios/MullvadVPNTests/OperationObserverTests.swift
@@ -9,7 +9,6 @@
import XCTest
class OperationObserverTests: XCTestCase {
-
func testBlockObserver() throws {
let expectDidAttach = expectation(description: "didAttach handler")
let expectDidStart = expectation(description: "didStart handler")
@@ -64,5 +63,4 @@ class OperationObserverTests: XCTestCase {
let expectations = [expectDidAttach, expectDidCancel, expectDidStart, expectDidFinish]
wait(for: expectations, timeout: 1, enforceOrder: true)
}
-
}
diff --git a/ios/MullvadVPNTests/OperationSmokeTests.swift b/ios/MullvadVPNTests/OperationSmokeTests.swift
index 0aaf74ef8c..c739e4e3c9 100644
--- a/ios/MullvadVPNTests/OperationSmokeTests.swift
+++ b/ios/MullvadVPNTests/OperationSmokeTests.swift
@@ -9,12 +9,11 @@
import XCTest
class OperationSmokeTests: XCTestCase {
-
func testBatch() {
let expect = expectation(description: "Expect all operations to finish.")
let operationQueue = AsyncOperationQueue()
- let operations = (1...500).flatMap { i -> [Operation] in
+ let operations = (1 ... 500).flatMap { i -> [Operation] in
let parent = BlockOperation()
parent.cancel()
@@ -35,5 +34,4 @@ class OperationSmokeTests: XCTestCase {
waitForExpectations(timeout: 1)
}
-
}
diff --git a/ios/MullvadVPNTests/RelaySelectorTests.swift b/ios/MullvadVPNTests/RelaySelectorTests.swift
index 8f997289db..82a602c951 100644
--- a/ios/MullvadVPNTests/RelaySelectorTests.swift
+++ b/ios/MullvadVPNTests/RelaySelectorTests.swift
@@ -6,11 +6,10 @@
// Copyright © 2019 Mullvad VPN AB. All rights reserved.
//
-import XCTest
import Network
+import XCTest
class RelaySelectorTests: XCTestCase {
-
func testCountryConstraint() throws {
let constraints = RelayConstraints(location: .only(.country("es")))
@@ -33,7 +32,6 @@ class RelaySelectorTests: XCTestCase {
XCTAssertEqual(result.relay.hostname, "se6-wireguard")
}
-
}
private let sampleRelays = REST.ServerRelaysResponse(
@@ -55,7 +53,7 @@ private let sampleRelays = REST.ServerRelaysResponse(
city: "Stockholm",
latitude: 59.3289,
longitude: 18.0649
- )
+ ),
],
wireguard: REST.ServerWireguardTunnels(
ipv4Gateway: .loopback,
@@ -109,6 +107,7 @@ private let sampleRelays = REST.ServerRelaysResponse(
ipv6AddrIn: .loopback,
publicKey: Data(),
includeInCountry: true
- )
- ])
+ ),
+ ]
+ )
)
diff --git a/ios/MullvadVPNTests/StringTests.swift b/ios/MullvadVPNTests/StringTests.swift
index e5db3c096a..4f5c3511f3 100644
--- a/ios/MullvadVPNTests/StringTests.swift
+++ b/ios/MullvadVPNTests/StringTests.swift
@@ -9,7 +9,6 @@
import XCTest
class StringTests: XCTestCase {
-
func testEmptyString() {
XCTAssertTrue("".split(every: 4).isEmpty)
}
@@ -25,5 +24,4 @@ class StringTests: XCTestCase {
func testStringShorterThanLength() {
XCTAssertEqual("1".split(every: 4), ["1"])
}
-
}
diff --git a/ios/PacketTunnel/PacketTunnelConfiguration.swift b/ios/PacketTunnel/PacketTunnelConfiguration.swift
index 69de080868..ef774489da 100644
--- a/ios/PacketTunnel/PacketTunnelConfiguration.swift
+++ b/ios/PacketTunnel/PacketTunnelConfiguration.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import WireGuardKit
import protocol Network.IPAddress
+import WireGuardKit
struct PacketTunnelConfiguration {
var deviceState: DeviceState
@@ -30,7 +30,7 @@ extension PacketTunnelConfiguration {
peerConfig.endpoint = endpoint
peerConfig.allowedIPs = [
IPAddressRange(from: "0.0.0.0/0")!,
- IPAddressRange(from: "::/0")!
+ IPAddressRange(from: "::/0")!,
]
return peerConfig
}
@@ -38,7 +38,7 @@ extension PacketTunnelConfiguration {
var interfaceConfig: InterfaceConfiguration
switch deviceState {
- case .loggedIn(_, let device):
+ case let .loggedIn(_, device):
interfaceConfig = InterfaceConfiguration(privateKey: device.wgKeyData.privateKey)
interfaceConfig.addresses = [device.ipv4Address, device.ipv6Address]
interfaceConfig.dns = dnsServers.map { DNSServer(address: $0) }
diff --git a/ios/PacketTunnel/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider.swift
index 01a3da6e03..89de247198 100644
--- a/ios/PacketTunnel/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider.swift
@@ -7,9 +7,9 @@
//
import Foundation
+import Logging
import Network
import NetworkExtension
-import Logging
import WireGuardKit
class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
@@ -71,17 +71,24 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
super.init()
- adapter = WireGuardAdapter(with: self, shouldHandleReasserting: false, logHandler: { [weak self] (logLevel, message) in
- self?.dispatchQueue.async {
- self?.tunnelLogger.log(level: logLevel.loggerLevel, "\(message)")
+ adapter = WireGuardAdapter(
+ with: self,
+ shouldHandleReasserting: false,
+ logHandler: { [weak self] logLevel, message in
+ self?.dispatchQueue.async {
+ self?.tunnelLogger.log(level: logLevel.loggerLevel, "\(message)")
+ }
}
- })
+ )
tunnelMonitor = TunnelMonitor(queue: dispatchQueue, adapter: adapter)
tunnelMonitor.delegate = self
}
- override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
+ override func startTunnel(
+ options: [String: NSObject]?,
+ completionHandler: @escaping (Error?) -> Void
+ ) {
let tunnelOptions = PacketTunnelOptions(rawOptions: options ?? [:])
var appSelectorResult: RelaySelectorResult?
@@ -90,7 +97,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
appSelectorResult = try tunnelOptions.getSelectorResult()
switch appSelectorResult {
- case .some(let selectorResult):
+ case let .some(selectorResult):
providerLogger.debug(
"Start the tunnel via app, connect to \(selectorResult.relay.hostname)."
)
@@ -107,9 +114,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
providerLogger.error(
chainedError: AnyChainedError(error),
message: """
- Failed to decode relay selector result passed from the app. \
- Will continue by picking new relay.
- """
+ Failed to decode relay selector result passed from the app. \
+ Will continue by picking new relay.
+ """
)
}
@@ -166,7 +173,10 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
}
}
- override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
+ override func stopTunnel(
+ with reason: NEProviderStopReason,
+ completionHandler: @escaping () -> Void
+ ) {
providerLogger.debug("Stop the tunnel: \(reason)")
dispatchQueue.async {
@@ -210,7 +220,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
self.providerLogger.debug("Received app message: \(message)")
switch message {
- case .reconnectTunnel(let appSelectorResult):
+ case let .reconnectTunnel(appSelectorResult):
self.providerLogger.debug("Reconnecting the tunnel...")
self.reconnectTunnel(selectorResult: appSelectorResult) { [weak self] error in
@@ -318,8 +328,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
func tunnelMonitor(
_ tunnelMonitor: TunnelMonitor,
networkReachabilityStatusDidChange isNetworkReachable: Bool
- )
- {
+ ) {
self.isNetworkReachable = isNetworkReachable
// Adjust the start reconnect date if tunnel monitor re-started pinging in response to
@@ -351,8 +360,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
private func reconnectTunnel(
selectorResult aSelectorResult: RelaySelectorResult?,
completionHandler: @escaping (Error?) -> Void
- )
- {
+ ) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
// Read tunnel configuration.
diff --git a/ios/PacketTunnel/TunnelMonitor/Pinger.swift b/ios/PacketTunnel/TunnelMonitor/Pinger.swift
index feb0fd678a..ca4071fef2 100644
--- a/ios/PacketTunnel/TunnelMonitor/Pinger.swift
+++ b/ios/PacketTunnel/TunnelMonitor/Pinger.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import struct Network.IPv4Address
import Logging
+import struct Network.IPv4Address
final class Pinger {
// Sender identifier passed along with ICMP packet.
@@ -39,7 +39,15 @@ final class Pinger {
stop()
- guard let newSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_DGRAM, IPPROTO_ICMP, 0, nil, nil) else {
+ guard let newSocket = CFSocketCreate(
+ kCFAllocatorDefault,
+ AF_INET,
+ SOCK_DGRAM,
+ IPPROTO_ICMP,
+ 0,
+ nil,
+ nil
+ ) else {
throw Error.createSocket
}
@@ -98,7 +106,11 @@ final class Pinger {
}
let sequenceNumber = nextSequenceNumber()
- let packetData = Self.createICMPPacket(identifier: identifier, sequenceNumber: sequenceNumber, payload: nil)
+ let packetData = Self.createICMPPacket(
+ identifier: identifier,
+ sequenceNumber: sequenceNumber,
+ payload: nil
+ )
let bytesSent = packetData.withUnsafeBytes { dataBuffer -> Int in
return withUnsafeBytes(of: &sa) { bufferPointer in
@@ -153,13 +165,20 @@ final class Pinger {
)
if result == -1 {
- logger.error("Failed to bind socket to \"\(interfaceName)\" (index: \(index), errno: \(errno)).")
+ logger
+ .error(
+ "Failed to bind socket to \"\(interfaceName)\" (index: \(index), errno: \(errno))."
+ )
throw Error.bindSocket(errno)
}
}
- private class func createICMPPacket(identifier: UInt16, sequenceNumber: UInt16, payload: Data?) -> Data {
+ private class func createICMPPacket(
+ identifier: UInt16,
+ sequenceNumber: UInt16,
+ payload: Data?
+ ) -> Data {
// Create data buffer.
var data = Data()
diff --git a/ios/PacketTunnel/TunnelMonitor/TunnelMonitor.swift b/ios/PacketTunnel/TunnelMonitor/TunnelMonitor.swift
index fd589e4aa1..60ee52a1ed 100644
--- a/ios/PacketTunnel/TunnelMonitor/TunnelMonitor.swift
+++ b/ios/PacketTunnel/TunnelMonitor/TunnelMonitor.swift
@@ -7,9 +7,9 @@
//
import Foundation
+import Logging
import NetworkExtension
import WireGuardKit
-import Logging
final class TunnelMonitor {
private let adapter: WireGuardAdapter
@@ -97,7 +97,7 @@ final class TunnelMonitor {
}
private func stopNoQueue(forRestart: Bool) {
- if isStarted && !forRestart {
+ if isStarted, !forRestart {
logger.debug("Stop tunnel monitor.")
}
@@ -142,7 +142,10 @@ final class TunnelMonitor {
timer?.setEventHandler { [weak self] in
self?.onWgStatsTimer()
}
- timer?.schedule(wallDeadline: .now(), repeating: TunnelMonitorConfiguration.wgStatsQueryInterval)
+ timer?.schedule(
+ wallDeadline: .now(),
+ repeating: TunnelMonitorConfiguration.wgStatsQueryInterval
+ )
timer?.resume()
logger.debug("Set WG stats timer.")
@@ -174,11 +177,14 @@ final class TunnelMonitor {
return
}
- let oldNetworkBytesReceived = self.networkBytesReceived
+ let oldNetworkBytesReceived = networkBytesReceived
networkBytesReceived = newNetworkBytesReceived
if newNetworkBytesReceived < oldNetworkBytesReceived {
- logger.debug("Stats was reset? newNetworkBytesReceived = \(newNetworkBytesReceived), oldNetworkBytesReceived = \(oldNetworkBytesReceived)")
+ logger
+ .debug(
+ "Stats was reset? newNetworkBytesReceived = \(newNetworkBytesReceived), oldNetworkBytesReceived = \(oldNetworkBytesReceived)"
+ )
return
}
@@ -194,7 +200,10 @@ final class TunnelMonitor {
return
}
- if let nextAttemptDate = lastAttemptDate?.addingTimeInterval(TunnelMonitorConfiguration.connectionTimeout), nextAttemptDate <= Date() {
+ if let nextAttemptDate = lastAttemptDate?
+ .addingTimeInterval(TunnelMonitorConfiguration.connectionTimeout),
+ nextAttemptDate <= Date()
+ {
// Reset the last recovery attempt date.
lastAttemptDate = nextAttemptDate
@@ -230,7 +239,10 @@ final class TunnelMonitor {
setWgStatsTimer()
delegateQueue.async {
- self.delegate?.tunnelMonitor(self, networkReachabilityStatusDidChange: isNetworkReachable)
+ self.delegate?.tunnelMonitor(
+ self,
+ networkReachabilityStatusDidChange: isNetworkReachable
+ )
}
} catch {
let error = error as! Pinger.Error
@@ -255,7 +267,10 @@ final class TunnelMonitor {
lastAttemptDate = nil
delegateQueue.async {
- self.delegate?.tunnelMonitor(self, networkReachabilityStatusDidChange: isNetworkReachable)
+ self.delegate?.tunnelMonitor(
+ self,
+ networkReachabilityStatusDidChange: isNetworkReachable
+ )
}
default:
@@ -301,7 +316,7 @@ final class TunnelMonitor {
}
if let endIndex = endIndex {
- return UInt64(string[startIndex..<endIndex])
+ return UInt64(string[startIndex ..< endIndex])
} else {
return nil
}
diff --git a/ios/PacketTunnel/WireGuardAdapterError+Localization.swift b/ios/PacketTunnel/WireGuardAdapterError+Localization.swift
index 7568c65b87..6a88af373d 100644
--- a/ios/PacketTunnel/WireGuardAdapterError+Localization.swift
+++ b/ios/PacketTunnel/WireGuardAdapterError+Localization.swift
@@ -18,7 +18,7 @@ extension WireGuardAdapterError: LocalizedError {
case .invalidState:
return "Failure to perform an operation in such state."
- case .dnsResolution(let resolutionErrors):
+ case let .dnsResolution(resolutionErrors):
let detailedErrorDescription = resolutionErrors
.enumerated()
.map { index, dnsResolutionError in
@@ -33,7 +33,7 @@ extension WireGuardAdapterError: LocalizedError {
case .setNetworkSettings:
return "Failure to set network settings."
- case .startWireGuardBackend(let code):
+ case let .startWireGuardBackend(code):
return "Failure to start WireGuard backend (error code: \(code))."
}
}
diff --git a/ios/PacketTunnel/WireGuardLogLevel+Logging.swift b/ios/PacketTunnel/WireGuardLogLevel+Logging.swift
index 443941c74e..4a59b8dbfb 100644
--- a/ios/PacketTunnel/WireGuardLogLevel+Logging.swift
+++ b/ios/PacketTunnel/WireGuardLogLevel+Logging.swift
@@ -7,8 +7,8 @@
//
import Foundation
-import WireGuardKit
import Logging
+import WireGuardKit
extension WireGuardLogLevel {
var loggerLevel: Logger.Level {