diff options
| author | Jon Petersson <jon.petersson@mullvad.net> | 2025-10-24 08:13:18 +0200 |
|---|---|---|
| committer | Jon Petersson <jon.petersson@mullvad.net> | 2025-10-24 08:13:18 +0200 |
| commit | 3fd0813021ce79818d39996ff089dfb8a5697ad4 (patch) | |
| tree | 289ecb097e4eca02b78bbecfb72d93215c173873 /ios/MullvadVPN | |
| parent | 63e9eb92c6e7a1aee6b682ed885d10a6f6fc699c (diff) | |
| parent | e1f357ea3b261265dca2ce0712b265f632079c37 (diff) | |
| download | mullvadvpn-3fd0813021ce79818d39996ff089dfb8a5697ad4.tar.xz mullvadvpn-3fd0813021ce79818d39996ff089dfb8a5697ad4.zip | |
Merge branch 'fetch-current-location-asynchronously-upon-first-start-of-ios-1328'
Diffstat (limited to 'ios/MullvadVPN')
| -rw-r--r-- | ios/MullvadVPN/AppDelegate.swift | 45 | ||||
| -rw-r--r-- | ios/MullvadVPN/Classes/AppPreferences.swift | 14 | ||||
| -rw-r--r-- | ios/MullvadVPN/Classes/FirstTimeLaunch.swift | 21 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Protocols/URLSessionProtocol.swift | 15 |
5 files changed, 55 insertions, 41 deletions
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index 4871b07e5a..1072b57a6e 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -48,7 +48,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD private var migrationManager: MigrationManager! nonisolated(unsafe) private(set) var accessMethodRepository = AccessMethodRepository() - private(set) var appPreferences = AppPreferences() + nonisolated(unsafe) private(set) var appPreferences = AppPreferences() private(set) var shadowsocksLoader: ShadowsocksLoader! private(set) var ipOverrideRepository = IPOverrideRepository() private(set) var relaySelector: RelaySelectorWrapper! @@ -491,16 +491,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD private func startInitialization(application: UIApplication) { let wipeSettingsOperation = getWipeSettingsOperation() + let defaultLocationOperation = getDefaultLocationOperation() let loadTunnelStoreOperation = getLoadTunnelStoreOperation() let migrateSettingsOperation = getMigrateSettingsOperation(application: application) let initTunnelManagerOperation = getInitTunnelManagerOperation() + defaultLocationOperation.addDependency(wipeSettingsOperation) migrateSettingsOperation.addDependencies([wipeSettingsOperation, loadTunnelStoreOperation]) initTunnelManagerOperation.addDependency(migrateSettingsOperation) operationQueue.addOperations( [ wipeSettingsOperation, + defaultLocationOperation, loadTunnelStoreOperation, migrateSettingsOperation, initTunnelManagerOperation, @@ -593,8 +596,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// compatible, thus triggering a settings wipe. private func getWipeSettingsOperation() -> AsyncBlockOperation { AsyncBlockOperation { - let appHasNeverBeenLaunched = !FirstTimeLaunch.hasFinished && !SettingsManager.getShouldWipeSettings() - let appWasLaunchedAfterReinstall = !FirstTimeLaunch.hasFinished && SettingsManager.getShouldWipeSettings() + let appHasNeverBeenLaunched = + !self.appPreferences.hasDoneFirstTimeLaunch && !SettingsManager.getShouldWipeSettings() + let appWasLaunchedAfterReinstall = + !self.appPreferences.hasDoneFirstTimeLaunch && SettingsManager.getShouldWipeSettings() if appHasNeverBeenLaunched { try? SettingsManager.writeSettings(LatestTunnelSettings()) @@ -622,11 +627,43 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD try? self.relayCacheTracker.refreshCachedRelays() } - FirstTimeLaunch.setHasFinished() SettingsManager.setShouldWipeSettings() } } + private func getDefaultLocationOperation() -> AsyncBlockOperation { + AsyncBlockOperation { + guard !self.appPreferences.hasDoneFirstTimeLaunch else { + return + } + self.appPreferences.hasDoneFirstTimeLaunch = true + + // No need to keep the handle since we're not waiting or cancelling the completion anyway. + _ = self.relayCacheTracker.updateRelays { _ in + Task { + guard let cachedRelays = try? self.relayCacheTracker.getCachedRelays() else { + return + } + + let locationService = DefaultLocationService( + urlSession: URLSession.shared, relayCache: cachedRelays) + let locationIdentifier = try? await locationService.fetchCurrentLocationIdentifier() + + let constraint = RelayConstraint.only( + UserSelectedRelays( + locations: [.country(locationIdentifier?.country ?? "se")] + )) + + if !self.appPreferences.hasDoneFirstTimeLogin { + self.tunnelManager.updateSettings([ + .relayConstraints(RelayConstraints(entryLocations: constraint, exitLocations: constraint)) + ]) + } + } + } + } + } + // MARK: - StorePaymentManagerDelegate nonisolated func storePaymentManager( diff --git a/ios/MullvadVPN/Classes/AppPreferences.swift b/ios/MullvadVPN/Classes/AppPreferences.swift index 31778ee742..103f17766a 100644 --- a/ios/MullvadVPN/Classes/AppPreferences.swift +++ b/ios/MullvadVPN/Classes/AppPreferences.swift @@ -10,16 +10,28 @@ import Foundation import MullvadSettings protocol AppPreferencesDataSource { + var hasDoneFirstTimeLaunch: Bool { get set } + var hasDoneFirstTimeLogin: Bool { get set } var isShownOnboarding: Bool { get set } var isAgreedToTermsOfService: Bool { get set } var lastSeenChangeLogVersion: String { get set } } enum AppStorageKey: String { - case isShownOnboarding, isAgreedToTermsOfService, lastSeenChangeLogVersion + case hasDoneFirstTimeLaunch = "hasFinishedFirstTimeLaunch" + case hasDoneFirstTimeLogin + case isShownOnboarding + case isAgreedToTermsOfService + case lastSeenChangeLogVersion } final class AppPreferences: AppPreferencesDataSource { + @AppStorage(key: AppStorageKey.hasDoneFirstTimeLaunch.rawValue, container: .standard) + var hasDoneFirstTimeLaunch: Bool = false + + @AppStorage(key: AppStorageKey.hasDoneFirstTimeLogin.rawValue, container: .standard) + var hasDoneFirstTimeLogin: Bool = false + @AppStorage(key: AppStorageKey.isShownOnboarding.rawValue, container: .standard) var isShownOnboarding = true diff --git a/ios/MullvadVPN/Classes/FirstTimeLaunch.swift b/ios/MullvadVPN/Classes/FirstTimeLaunch.swift deleted file mode 100644 index d7ee4ec5fa..0000000000 --- a/ios/MullvadVPN/Classes/FirstTimeLaunch.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// FirstTimeLaunch.swift -// MullvadVPN -// -// Created by Jon Petersson on 2023-04-04. -// Copyright © 2025 Mullvad VPN AB. All rights reserved. -// - -import Foundation - -enum FirstTimeLaunch { - private static let userDefaultsKey = "hasFinishedFirstTimeLaunch" - - static var hasFinished: Bool { - UserDefaults.standard.bool(forKey: userDefaultsKey) - } - - static func setHasFinished() { - UserDefaults.standard.set(true, forKey: userDefaultsKey) - } -} diff --git a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift index e7121b28ef..f135633a3e 100644 --- a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift @@ -466,6 +466,7 @@ final class ApplicationCoordinator: Coordinator, Presenting, @preconcurrency Roo coordinator.preferredAccountNumberPublisher = preferredAccountNumberSubject.eraseToAnyPublisher() coordinator.didFinish = { [weak self] _ in + self?.appPreferences.hasDoneFirstTimeLogin = true self?.continueFlow(animated: true) } coordinator.didCreateAccount = { [weak self] in diff --git a/ios/MullvadVPN/Protocols/URLSessionProtocol.swift b/ios/MullvadVPN/Protocols/URLSessionProtocol.swift deleted file mode 100644 index b3ca239120..0000000000 --- a/ios/MullvadVPN/Protocols/URLSessionProtocol.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// URLSessionProtocol.swift -// MullvadVPN -// -// Created by Jon Petersson on 2023-11-16. -// Copyright © 2025 Mullvad VPN AB. All rights reserved. -// - -import Foundation - -protocol URLSessionProtocol { - func data(for request: URLRequest) async throws -> (Data, URLResponse) -} - -extension URLSession: URLSessionProtocol {} |
