diff options
| author | Jon Petersson <jon.petersson@mullvad.net> | 2025-08-12 14:50:01 +0200 |
|---|---|---|
| committer | Jon Petersson <jon.petersson@mullvad.net> | 2025-08-12 14:50:01 +0200 |
| commit | 2ebbcdfc72d3435c9ef95f91ddfb1cd74f4f4ec0 (patch) | |
| tree | 97407167d76af1ee097fdf1a3597b3f34f82cf2b /ios/MullvadSettings | |
| parent | cf0cb9934d732b045803c0affce291d11c6251fa (diff) | |
| parent | 1b7d4c9f171b5ba157f0c27fa0de3ab627c6fe14 (diff) | |
| download | mullvadvpn-2ebbcdfc72d3435c9ef95f91ddfb1cd74f4f4ec0.tar.xz mullvadvpn-2ebbcdfc72d3435c9ef95f91ddfb1cd74f4f4ec0.zip | |
Merge branch 'ios-1214-propagate-method-rotation'
Diffstat (limited to 'ios/MullvadSettings')
3 files changed, 57 insertions, 12 deletions
diff --git a/ios/MullvadSettings/AccessMethodRepository.swift b/ios/MullvadSettings/AccessMethodRepository.swift index 72cfc0668e..07e1ad2a61 100644 --- a/ios/MullvadSettings/AccessMethodRepository.swift +++ b/ios/MullvadSettings/AccessMethodRepository.swift @@ -46,26 +46,40 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked accessMethodsSubject.eraseToAnyPublisher() } - private let lastReachableAccessMethodSubject: CurrentValueSubject<PersistentAccessMethod, Never> - public var lastReachableAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { - lastReachableAccessMethodSubject.eraseToAnyPublisher() + private let requestAccessMethodSubject: PassthroughSubject<PersistentAccessMethod, Never> + public var requestAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { + requestAccessMethodSubject.eraseToAnyPublisher() + } + + private let currentAccessMethodSubject: CurrentValueSubject<PersistentAccessMethod, Never> + public var currentAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { + currentAccessMethodSubject.eraseToAnyPublisher() } public var directAccess: PersistentAccessMethod { direct } + private var cancellables: Set<Combine.AnyCancellable> = [] + public init() { accessMethodsSubject = CurrentValueSubject([]) - lastReachableAccessMethodSubject = CurrentValueSubject(direct) + requestAccessMethodSubject = PassthroughSubject() + currentAccessMethodSubject = CurrentValueSubject(direct) addDefaultsMethods() accessMethodsSubject.send(fetchAll()) - lastReachableAccessMethodSubject.send(fetchLastReachable()) + requestAccessMethodSubject.send(fetchLastReachable()) + + currentAccessMethodPublisher + .removeDuplicates() + .sink { [weak self] currentAccessMethod in + self?.saveCurrentAccessMethod(currentAccessMethod) + }.store(in: &cancellables) } - public func save(_ method: PersistentAccessMethod) { + public func save(_ method: PersistentAccessMethod, notifyingAPI: Bool = false) { var methodStore = readApiAccessMethodStore() var method = method @@ -79,19 +93,24 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked do { try writeApiAccessMethodStore(methodStore) - accessMethodsSubject.send(methodStore.accessMethods) + if notifyingAPI { + accessMethodsSubject.send(methodStore.accessMethods) + } } catch { logger.error("Could not save access method: \(method) \nError: \(error)") } } - public func saveLastReachable(_ method: PersistentAccessMethod) { + public func requestAccessMethod(_ method: PersistentAccessMethod) { + requestAccessMethodSubject.send(method) + } + + private func saveCurrentAccessMethod(_ method: PersistentAccessMethod) { var methodStore = readApiAccessMethodStore() methodStore.lastReachableAccessMethod = method do { try writeApiAccessMethodStore(methodStore) - lastReachableAccessMethodSubject.send(method) } catch { logger.error("Could not save last reachable access method: \(method) \nError: \(error)") } @@ -175,3 +194,17 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked SettingsParser(decoder: JSONDecoder(), encoder: JSONEncoder()) } } + +extension AccessMethodRepository: MullvadAccessMethodChangeListening { + public func accessMethodChangedTo(_ uuid: UUID) { + guard let method = accessMethodsSubject.value.first(where: { $0.id == uuid }) else { + logger.warning("Change reported to method with unknown ID: \(uuid)") + return + } + + Task { + print("Mullvad API changed access method to \(method.name)") + currentAccessMethodSubject.send(method) + } + } +} diff --git a/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift b/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift index 35f97442f5..d44f009911 100644 --- a/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift +++ b/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift @@ -21,7 +21,7 @@ public protocol AccessMethodRepositoryDataSource: Sendable { func fetchAll() -> [PersistentAccessMethod] /// Save last reachable access method to the persistent store. - func saveLastReachable(_ method: PersistentAccessMethod) + func requestAccessMethod(_ method: PersistentAccessMethod) /// Fetch last reachable access method from the persistent store. func fetchLastReachable() -> PersistentAccessMethod @@ -29,11 +29,11 @@ public protocol AccessMethodRepositoryDataSource: Sendable { public protocol AccessMethodRepositoryProtocol: AccessMethodRepositoryDataSource { /// Publisher that propagates a snapshot of last reachable access method upon modifications. - var lastReachableAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { get } + var currentAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { get } /// Add new access method. /// - Parameter method: persistent access method model. - func save(_ method: PersistentAccessMethod) + func save(_ method: PersistentAccessMethod, notifyingAPI: Bool) /// Delete access method by id. /// - Parameter id: an access method id. diff --git a/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift b/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift new file mode 100644 index 0000000000..679d5e66fb --- /dev/null +++ b/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift @@ -0,0 +1,12 @@ +// +// MullvadAccessMethodChangeListening.swift +// MullvadVPN +// +// Created by Andrew Bulhak on 2025-07-03. +// Copyright © 2025 Mullvad VPN AB. All rights reserved. +// + +// A protocol that listens for notifications of when the current access method has changed. It receives only the UUID of the new method. +public protocol MullvadAccessMethodChangeListening: AnyObject { + func accessMethodChangedTo(_ uuid: UUID) +} |
