From 2f67bcbbf204f352a6dd0dacd28372d6d478404f Mon Sep 17 00:00:00 2001 From: Davide Date: Sat, 4 Jan 2025 23:42:10 +0100 Subject: [PATCH] Sync local profiles consistently (#1051) Rather than redoing ProfileManager.observeLocal() altogether: - Keep the existing profiles subscription (localSubscription) - Reload ALL local profiles on NE notifications The reload is "heavy" because each profile save causes a reload of ALL profiles, but it's the most reliable approach and in the end, it only takes 1-2msec. It can be improved later. Partially reverts #1049, because the app did not sync when a VPN configuration was deleted from the OS settings. --- Library/Package.resolved | 2 +- Library/Package.swift | 2 +- .../Strategy/NEProfileRepository.swift | 36 ++++--------------- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/Library/Package.resolved b/Library/Package.resolved index 5a37d559..1a9a4f73 100644 --- a/Library/Package.resolved +++ b/Library/Package.resolved @@ -41,7 +41,7 @@ "kind" : "remoteSourceControl", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "state" : { - "revision" : "6c98ac490edace667f2587ffaf57a5b6a467aa52" + "revision" : "8ced87ec9ea088603798be820ab8e2f1e71c2196" } }, { diff --git a/Library/Package.swift b/Library/Package.swift index 0506cd8f..495a7419 100644 --- a/Library/Package.swift +++ b/Library/Package.swift @@ -62,7 +62,7 @@ let package = Package( ], dependencies: [ // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.14.0"), - .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "6c98ac490edace667f2587ffaf57a5b6a467aa52"), + .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "8ced87ec9ea088603798be820ab8e2f1e71c2196"), // .package(path: "../../passepartoutkit-source"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "1.0.0"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "12c8b9166ba2bf98b63d3ebc5b561ac2ac5a2f86"), diff --git a/Library/Sources/CommonLibrary/Strategy/NEProfileRepository.swift b/Library/Sources/CommonLibrary/Strategy/NEProfileRepository.swift index b0c69645..5b421afe 100644 --- a/Library/Sources/CommonLibrary/Strategy/NEProfileRepository.swift +++ b/Library/Sources/CommonLibrary/Strategy/NEProfileRepository.swift @@ -45,7 +45,6 @@ public final class NEProfileRepository: ProfileRepository { repository .managersPublisher - .dropFirst() .sink { [weak self] in self?.onUpdatedManagers($0) } @@ -72,26 +71,14 @@ public final class NEProfileRepository: ProfileRepository { public func saveProfile(_ profile: Profile) async throws { try await repository.save(profile, forConnecting: false, options: nil, title: title) - if let index = profilesSubject.value.firstIndex(where: { $0.id == profile.id }) { - profilesSubject.value[index] = profile - } else { - profilesSubject.value.append(profile) - } } public func removeProfiles(withIds profileIds: [Profile.ID]) async throws { guard !profileIds.isEmpty else { return } - var removedIds: Set = [] - defer { - profilesSubject.value.removeAll { - removedIds.contains($0.id) - } - } for id in profileIds { try await repository.remove(profileId: id) - removedIds.insert(id) } } @@ -102,25 +89,14 @@ public final class NEProfileRepository: ProfileRepository { private extension NEProfileRepository { func onUpdatedManagers(_ managers: [Profile.ID: NETunnelProviderManager]) { - let profiles = profilesSubject - .value - .filter { - managers.keys.contains($0.id) + let profiles = managers.values.compactMap { + do { + return try repository.profile(from: $0) + } catch { + pp_log(.App.profiles, .error, "Unable to decode profile from NE manager '\($0.localizedDescription ?? "")': \(error)") + return nil } - - let removedProfilesDescription = profilesSubject - .value - .filter { - !managers.keys.contains($0.id) - } - .map { - "\($0.name)(\($0.id)" - } - - if !removedProfilesDescription.isEmpty { - pp_log(.App.profiles, .info, "Sync profiles removed externally: \(removedProfilesDescription)") } - profilesSubject.send(profiles) } }