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
)
persistenceManager = PersistenceManager(store: store)
persistenceManager = PersistenceManager(
store: store,
ckContainerId: Constants.CloudKit.containerId,
ckCoreDataZone: Constants.CloudKit.coreDataZone
)
reviewer = Reviewer()
reviewer.eventCountBeforeRating = Constants.Rating.eventCount

View File

@ -23,7 +23,6 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
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())

View File

@ -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<Void, Never>()
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