diff --git a/Passepartout/Library/Sources/AppLibrary/Business/ProfileManager.swift b/Passepartout/Library/Sources/AppLibrary/Business/ProfileManager.swift index df7477c2..c687b28a 100644 --- a/Passepartout/Library/Sources/AppLibrary/Business/ProfileManager.swift +++ b/Passepartout/Library/Sources/AppLibrary/Business/ProfileManager.swift @@ -37,6 +37,8 @@ public final class ProfileManager: ObservableObject { private let repository: any ProfileRepository + private let backupRepository: (any ProfileRepository)? + private let remoteRepository: (any ProfileRepository)? @Published @@ -59,6 +61,7 @@ public final class ProfileManager: ObservableObject { // for testing/previews public init(profiles: [Profile]) { repository = InMemoryProfileRepository(profiles: profiles) + backupRepository = nil remoteRepository = nil self.profiles = [] allProfiles = profiles.reduce(into: [:]) { @@ -71,8 +74,13 @@ public final class ProfileManager: ObservableObject { subscriptions = [] } - public init(repository: any ProfileRepository, remoteRepository: (any ProfileRepository)?) { + public init( + repository: any ProfileRepository, + backupRepository: (any ProfileRepository)? = nil, + remoteRepository: (any ProfileRepository)? + ) { self.repository = repository + self.backupRepository = backupRepository self.remoteRepository = remoteRepository profiles = [] allProfiles = [:] @@ -116,7 +124,13 @@ extension ProfileManager { do { let existingProfile = allProfiles[profile.id] if existingProfile == nil || profile != existingProfile { - try await repository.saveProfile(profile) + try await repository.saveProfile(profile) + + if let backupRepository { + Task.detached { + try? await backupRepository.saveProfile(profile) + } + } allProfiles[profile.id] = profile didChange.send(.save(profile)) diff --git a/Passepartout/Shared/Shared+App.swift b/Passepartout/Shared/Shared+App.swift index b2b0e2f1..09a278c3 100644 --- a/Passepartout/Shared/Shared+App.swift +++ b/Passepartout/Shared/Shared+App.swift @@ -49,8 +49,6 @@ extension AppContext { extension ProfileManager { static let shared: ProfileManager = { - let repository = localProfileRepository - let remoteStore = CoreDataPersistentStore( logger: .default, containerName: Constants.shared.containers.remote, @@ -68,7 +66,11 @@ extension ProfileManager { return .ignore } - return ProfileManager(repository: repository, remoteRepository: remoteRepository) + return ProfileManager( + repository: mainProfileRepository, + backupRepository: backupProfileRepository, + remoteRepository: remoteRepository + ) }() } @@ -158,7 +160,51 @@ extension Tunnel { } private extension ProfileManager { - static let localProfileRepository: ProfileRepository = { + static var mainProfileRepository: ProfileRepository { + coreDataProfileRepository + } + + static var backupProfileRepository: ProfileRepository? { + nil + } +} + +#else + +extension Tunnel { + static let shared = Tunnel( + strategy: ProfileManager.neStrategy + ) +} + +private extension ProfileManager { + static var mainProfileRepository: ProfileRepository { + neProfileRepository + } + + static var backupProfileRepository: ProfileRepository? { + coreDataProfileRepository + } +} + +#endif + +private extension ProfileManager { + static let neProfileRepository: ProfileRepository = { + NEProfileRepository(repository: neStrategy) { + ProfileManager.sharedTitle($0) + } + }() + + static let neStrategy: NETunnelStrategy = { + NETunnelStrategy( + bundleIdentifier: BundleConfiguration.mainString(for: .tunnelId), + coder: Registry.sharedProtocolCoder, + environment: .shared + ) + }() + + static let coreDataProfileRepository: ProfileRepository = { let store = CoreDataPersistentStore( logger: .default, containerName: Constants.shared.containers.local, @@ -178,32 +224,6 @@ private extension ProfileManager { }() } -#else - -extension Tunnel { - static let shared = Tunnel( - strategy: ProfileManager.neStrategy - ) -} - -private extension ProfileManager { - static let localProfileRepository: ProfileRepository = { - NEProfileRepository(repository: neStrategy) { - ProfileManager.sharedTitle($0) - } - }() - - static let neStrategy: NETunnelStrategy = { - NETunnelStrategy( - bundleIdentifier: BundleConfiguration.mainString(for: .tunnelId), - coder: Registry.sharedProtocolCoder, - environment: .shared - ) - }() -} - -#endif - // MARK: - // FIXME: #705, store providers to Core Data