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.
This commit is contained in:
Davide De Rosa 2023-09-10 11:20:56 +02:00 committed by GitHub
parent 0b755c1c77
commit f32c6f8fde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 18 deletions

View File

@ -61,7 +61,11 @@ final class AppContext {
buildProducts: Constants.InApp.buildProducts buildProducts: Constants.InApp.buildProducts
) )
persistenceManager = PersistenceManager(store: store) persistenceManager = PersistenceManager(
store: store,
ckContainerId: Constants.CloudKit.containerId,
ckCoreDataZone: Constants.CloudKit.coreDataZone
)
reviewer = Reviewer() reviewer = Reviewer()
reviewer.eventCountBeforeRating = Constants.Rating.eventCount reviewer.eventCountBeforeRating = Constants.Rating.eventCount

View File

@ -23,7 +23,6 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>. // along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
// //
import CloudKit
import Combine import Combine
import Foundation import Foundation
import PassepartoutLibrary import PassepartoutLibrary
@ -45,10 +44,10 @@ final class CoreContext {
init(persistenceManager: PersistenceManager) { init(persistenceManager: PersistenceManager) {
store = persistenceManager.store store = persistenceManager.store
let vpnPersistence = persistenceManager.vpnPersistence( let vpnPersistence = persistenceManager.loadVPNPersistence(
withName: Constants.Persistence.profilesContainerName withName: Constants.Persistence.profilesContainerName
) )
let providersPersistence = persistenceManager.providersPersistence( let providersPersistence = persistenceManager.loadProvidersPersistence(
withName: Constants.Persistence.providersContainerName withName: Constants.Persistence.providersContainerName
) )
@ -118,16 +117,12 @@ private extension CoreContext {
persistenceManager.didChangePersistence persistenceManager.didChangePersistence
.sink { [weak self] in .sink { [weak self] in
self?.reloadCloudKitObjects(persistenceManager: persistenceManager) self?.reloadPersistenceObjects(persistenceManager: persistenceManager)
}.store(in: &cancellables) }.store(in: &cancellables)
} }
}
// MARK: CloudKit func reloadPersistenceObjects(persistenceManager: PersistenceManager) {
let vpnPersistence = persistenceManager.loadVPNPersistence(
extension CoreContext {
func reloadCloudKitObjects(persistenceManager: PersistenceManager) {
let vpnPersistence = persistenceManager.vpnPersistence(
withName: Constants.Persistence.profilesContainerName withName: Constants.Persistence.profilesContainerName
) )
profileManager.swapProfileRepository(vpnPersistence.profileRepository()) profileManager.swapProfileRepository(vpnPersistence.profileRepository())

View File

@ -32,6 +32,14 @@ import PassepartoutLibrary
final class PersistenceManager: ObservableObject { final class PersistenceManager: ObservableObject {
let store: KeyValueStore let store: KeyValueStore
private let ckContainerId: String
private let ckCoreDataZone: String
private var vpnPersistence: VPNPersistence?
private var providersPersistence: ProvidersPersistence?
private(set) var isCloudSyncingEnabled: Bool { private(set) var isCloudSyncingEnabled: Bool {
didSet { didSet {
pp_log.info("CloudKit enabled: \(isCloudSyncingEnabled)") pp_log.info("CloudKit enabled: \(isCloudSyncingEnabled)")
@ -43,8 +51,10 @@ final class PersistenceManager: ObservableObject {
let didChangePersistence = PassthroughSubject<Void, Never>() let didChangePersistence = PassthroughSubject<Void, Never>()
init(store: KeyValueStore) { init(store: KeyValueStore, ckContainerId: String, ckCoreDataZone: String) {
self.store = store self.store = store
self.ckContainerId = ckContainerId
self.ckCoreDataZone = ckCoreDataZone
isCloudSyncingEnabled = store.canEnableCloudSyncing isCloudSyncingEnabled = store.canEnableCloudSyncing
// set once // set once
@ -53,12 +63,16 @@ final class PersistenceManager: ObservableObject {
} }
} }
func vpnPersistence(withName containerName: String) -> VPNPersistence { func loadVPNPersistence(withName containerName: String) -> VPNPersistence {
VPNPersistence(withName: containerName, cloudKit: isCloudSyncingEnabled, author: persistenceAuthor) let persistence = VPNPersistence(withName: containerName, cloudKit: isCloudSyncingEnabled, author: persistenceAuthor)
vpnPersistence = persistence
return persistence
} }
func providersPersistence(withName containerName: String) -> ProvidersPersistence { func loadProvidersPersistence(withName containerName: String) -> ProvidersPersistence {
ProvidersPersistence(withName: containerName, cloudKit: false, author: persistenceAuthor) let persistence = ProvidersPersistence(withName: containerName, cloudKit: false, author: persistenceAuthor)
providersPersistence = persistence
return persistence
} }
} }
@ -70,8 +84,8 @@ extension PersistenceManager {
isErasingCloudKitStore = true isErasingCloudKitStore = true
} }
await Self.eraseCloudKitStore( await Self.eraseCloudKitStore(
fromContainerWithId: Constants.CloudKit.containerId, fromContainerWithId: ckContainerId,
zoneId: .init(zoneName: Constants.CloudKit.coreDataZone) zoneId: .init(zoneName: ckCoreDataZone)
) )
await MainActor.run { await MainActor.run {
isErasingCloudKitStore = false isErasingCloudKitStore = false