From f32c6f8fdeec66d44200f2c989c5c294b2cfa3a4 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sun, 10 Sep 2023 11:20:56 +0200 Subject: [PATCH] Retain persistence objects in manager (#357) Relying on Core Data for context retention is fragile, better to keep a reference of the *Persistence objects ourselves. Also, remove any CloudKit reference from CoreContext. --- Passepartout/App/Context/AppContext.swift | 6 +++- Passepartout/App/Context/CoreContext.swift | 15 ++++------ .../App/Managers/PersistenceManager.swift | 28 ++++++++++++++----- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Passepartout/App/Context/AppContext.swift b/Passepartout/App/Context/AppContext.swift index 9c1c1d1e..707f49ab 100644 --- a/Passepartout/App/Context/AppContext.swift +++ b/Passepartout/App/Context/AppContext.swift @@ -61,7 +61,11 @@ final class AppContext { buildProducts: Constants.InApp.buildProducts ) - persistenceManager = PersistenceManager(store: store) + persistenceManager = PersistenceManager( + store: store, + ckContainerId: Constants.CloudKit.containerId, + ckCoreDataZone: Constants.CloudKit.coreDataZone + ) reviewer = Reviewer() reviewer.eventCountBeforeRating = Constants.Rating.eventCount diff --git a/Passepartout/App/Context/CoreContext.swift b/Passepartout/App/Context/CoreContext.swift index 545d68d8..94fbe79c 100644 --- a/Passepartout/App/Context/CoreContext.swift +++ b/Passepartout/App/Context/CoreContext.swift @@ -23,7 +23,6 @@ // along with Passepartout. If not, see . // -import CloudKit import Combine import Foundation import PassepartoutLibrary @@ -45,10 +44,10 @@ final class CoreContext { init(persistenceManager: PersistenceManager) { store = persistenceManager.store - let vpnPersistence = persistenceManager.vpnPersistence( + let vpnPersistence = persistenceManager.loadVPNPersistence( withName: Constants.Persistence.profilesContainerName ) - let providersPersistence = persistenceManager.providersPersistence( + let providersPersistence = persistenceManager.loadProvidersPersistence( withName: Constants.Persistence.providersContainerName ) @@ -118,16 +117,12 @@ private extension CoreContext { persistenceManager.didChangePersistence .sink { [weak self] in - self?.reloadCloudKitObjects(persistenceManager: persistenceManager) + self?.reloadPersistenceObjects(persistenceManager: persistenceManager) }.store(in: &cancellables) } -} -// MARK: CloudKit - -extension CoreContext { - func reloadCloudKitObjects(persistenceManager: PersistenceManager) { - let vpnPersistence = persistenceManager.vpnPersistence( + func reloadPersistenceObjects(persistenceManager: PersistenceManager) { + let vpnPersistence = persistenceManager.loadVPNPersistence( withName: Constants.Persistence.profilesContainerName ) profileManager.swapProfileRepository(vpnPersistence.profileRepository()) diff --git a/Passepartout/App/Managers/PersistenceManager.swift b/Passepartout/App/Managers/PersistenceManager.swift index 64e8aa3d..8db4ea82 100644 --- a/Passepartout/App/Managers/PersistenceManager.swift +++ b/Passepartout/App/Managers/PersistenceManager.swift @@ -32,6 +32,14 @@ import PassepartoutLibrary final class PersistenceManager: ObservableObject { let store: KeyValueStore + private let ckContainerId: String + + private let ckCoreDataZone: String + + private var vpnPersistence: VPNPersistence? + + private var providersPersistence: ProvidersPersistence? + private(set) var isCloudSyncingEnabled: Bool { didSet { pp_log.info("CloudKit enabled: \(isCloudSyncingEnabled)") @@ -43,8 +51,10 @@ final class PersistenceManager: ObservableObject { let didChangePersistence = PassthroughSubject() - init(store: KeyValueStore) { + init(store: KeyValueStore, ckContainerId: String, ckCoreDataZone: String) { self.store = store + self.ckContainerId = ckContainerId + self.ckCoreDataZone = ckCoreDataZone isCloudSyncingEnabled = store.canEnableCloudSyncing // set once @@ -53,12 +63,16 @@ final class PersistenceManager: ObservableObject { } } - func vpnPersistence(withName containerName: String) -> VPNPersistence { - VPNPersistence(withName: containerName, cloudKit: isCloudSyncingEnabled, author: persistenceAuthor) + func loadVPNPersistence(withName containerName: String) -> VPNPersistence { + let persistence = VPNPersistence(withName: containerName, cloudKit: isCloudSyncingEnabled, author: persistenceAuthor) + vpnPersistence = persistence + return persistence } - func providersPersistence(withName containerName: String) -> ProvidersPersistence { - ProvidersPersistence(withName: containerName, cloudKit: false, author: persistenceAuthor) + func loadProvidersPersistence(withName containerName: String) -> ProvidersPersistence { + let persistence = ProvidersPersistence(withName: containerName, cloudKit: false, author: persistenceAuthor) + providersPersistence = persistence + return persistence } } @@ -70,8 +84,8 @@ extension PersistenceManager { isErasingCloudKitStore = true } await Self.eraseCloudKitStore( - fromContainerWithId: Constants.CloudKit.containerId, - zoneId: .init(zoneName: Constants.CloudKit.coreDataZone) + fromContainerWithId: ckContainerId, + zoneId: .init(zoneName: ckCoreDataZone) ) await MainActor.run { isErasingCloudKitStore = false