Encapsulate *Persistence responsibilities (#305)
Do not leave the choice of a repository context up to the library consumer. Instead, provide a specific factory (*Persistence) for each module.
This commit is contained in:
parent
efcda495bc
commit
a78a7b18b5
|
@ -33,18 +33,18 @@ import TunnelKitManager
|
||||||
final class CoreContext {
|
final class CoreContext {
|
||||||
let store: KeyValueStore
|
let store: KeyValueStore
|
||||||
|
|
||||||
private let profilesPersistence: CoreDataPersistentStore
|
private let providersPersistence: ProvidersPersistence
|
||||||
|
|
||||||
private let providersPersistence: CoreDataPersistentStore
|
private let vpnPersistence: VPNPersistence
|
||||||
|
|
||||||
var urlsForProfiles: [URL]? {
|
|
||||||
profilesPersistence.containerURLs
|
|
||||||
}
|
|
||||||
|
|
||||||
var urlsForProviders: [URL]? {
|
var urlsForProviders: [URL]? {
|
||||||
providersPersistence.containerURLs
|
providersPersistence.containerURLs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var urlsForProfiles: [URL]? {
|
||||||
|
vpnPersistence.containerURLs
|
||||||
|
}
|
||||||
|
|
||||||
let upgradeManager: UpgradeManager
|
let upgradeManager: UpgradeManager
|
||||||
|
|
||||||
let providerManager: ProviderManager
|
let providerManager: ProviderManager
|
||||||
|
@ -67,7 +67,7 @@ final class CoreContext {
|
||||||
pp_log.info("Logging to: \(logger.logFile!)")
|
pp_log.info("Logging to: \(logger.logFile!)")
|
||||||
|
|
||||||
let persistenceManager = PersistenceManager(store: store)
|
let persistenceManager = PersistenceManager(store: store)
|
||||||
profilesPersistence = persistenceManager.profilesPersistence(
|
vpnPersistence = persistenceManager.vpnPersistence(
|
||||||
withName: Constants.Persistence.profilesContainerName
|
withName: Constants.Persistence.profilesContainerName
|
||||||
)
|
)
|
||||||
providersPersistence = persistenceManager.providersPersistence(
|
providersPersistence = persistenceManager.providersPersistence(
|
||||||
|
@ -89,17 +89,17 @@ final class CoreContext {
|
||||||
Constants.Repos.api,
|
Constants.Repos.api,
|
||||||
timeout: Constants.Services.connectivityTimeout
|
timeout: Constants.Services.connectivityTimeout
|
||||||
),
|
),
|
||||||
webServicesRepository: PassepartoutPersistence.webServicesRepository(providersPersistence)
|
webServicesRepository: providersPersistence.webServicesRepository()
|
||||||
)
|
)
|
||||||
providerManager = ProviderManager(
|
providerManager = ProviderManager(
|
||||||
localProvidersRepository: PassepartoutPersistence.localProvidersRepository(providersPersistence),
|
localProvidersRepository: providersPersistence.localProvidersRepository(),
|
||||||
remoteProvidersStrategy: remoteProvidersStrategy
|
remoteProvidersStrategy: remoteProvidersStrategy
|
||||||
)
|
)
|
||||||
|
|
||||||
profileManager = ProfileManager(
|
profileManager = ProfileManager(
|
||||||
store: store,
|
store: store,
|
||||||
providerManager: providerManager,
|
providerManager: providerManager,
|
||||||
profileRepository: PassepartoutPersistence.profileRepository(profilesPersistence),
|
profileRepository: vpnPersistence.profileRepository(),
|
||||||
keychain: KeychainSecretRepository(appGroup: Constants.App.appGroupId),
|
keychain: KeychainSecretRepository(appGroup: Constants.App.appGroupId),
|
||||||
keychainEntry: Unlocalized.Keychain.passwordEntry,
|
keychainEntry: Unlocalized.Keychain.passwordEntry,
|
||||||
keychainLabel: Unlocalized.Keychain.passwordLabel
|
keychainLabel: Unlocalized.Keychain.passwordLabel
|
||||||
|
|
|
@ -39,12 +39,12 @@ final class PersistenceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func profilesPersistence(withName containerName: String) -> CoreDataPersistentStore {
|
func vpnPersistence(withName containerName: String) -> VPNPersistence {
|
||||||
PassepartoutPersistence.profilesStore(withName: containerName, cloudKit: true, author: persistenceAuthor)
|
VPNPersistence(withName: containerName, cloudKit: true, author: persistenceAuthor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func providersPersistence(withName containerName: String) -> CoreDataPersistentStore {
|
func providersPersistence(withName containerName: String) -> ProvidersPersistence {
|
||||||
PassepartoutPersistence.providersStore(withName: containerName, cloudKit: false, author: persistenceAuthor)
|
ProvidersPersistence(withName: containerName, cloudKit: false, author: persistenceAuthor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,6 @@ public class Passepartout {
|
||||||
public var logger: Logger = DefaultLogger()
|
public var logger: Logger = DefaultLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PassepartoutPersistence {
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct PassepartoutError: Error, Equatable {
|
public struct PassepartoutError: Error, Equatable {
|
||||||
private let string: String
|
private let string: String
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Persistence.swift
|
// ProvidersPersistence.swift
|
||||||
// Passepartout
|
// Passepartout
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 4/7/22.
|
// Created by Davide De Rosa on 4/7/22.
|
||||||
|
@ -29,30 +29,34 @@ import PassepartoutCore
|
||||||
import PassepartoutProviders
|
import PassepartoutProviders
|
||||||
import PassepartoutServices
|
import PassepartoutServices
|
||||||
|
|
||||||
extension PassepartoutPersistence {
|
public final class ProvidersPersistence {
|
||||||
private static let providersDataModel: NSManagedObjectModel = {
|
private static let dataModel: NSManagedObjectModel = {
|
||||||
guard let model = NSManagedObjectModel.mergedModel(from: [.module]) else {
|
guard let model = NSManagedObjectModel.mergedModel(from: [.module]) else {
|
||||||
fatalError("Could not load PassepartoutProviders model")
|
fatalError("Could not load PassepartoutProviders model")
|
||||||
}
|
}
|
||||||
return model
|
return model
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public static func providersStore(withName containerName: String, cloudKit: Bool, author: String?) -> CoreDataPersistentStore {
|
private let store: CoreDataPersistentStore
|
||||||
.init(
|
|
||||||
|
public var containerURLs: [URL]? {
|
||||||
|
store.containerURLs
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(withName containerName: String, cloudKit: Bool, author: String?) {
|
||||||
|
store = .init(
|
||||||
withName: containerName,
|
withName: containerName,
|
||||||
model: providersDataModel,
|
model: Self.dataModel,
|
||||||
cloudKit: cloudKit,
|
cloudKit: cloudKit,
|
||||||
author: author
|
author: author
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
extension PassepartoutPersistence {
|
public func webServicesRepository() -> WebServicesRepository {
|
||||||
public static func webServicesRepository(_ store: CoreDataPersistentStore) -> WebServicesRepository {
|
|
||||||
CDWebServicesRepository(store.context)
|
CDWebServicesRepository(store.context)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func localProvidersRepository(_ store: CoreDataPersistentStore) -> LocalProvidersRepository {
|
public func localProvidersRepository() -> LocalProvidersRepository {
|
||||||
CDLocalProvidersRepository(store.context)
|
CDLocalProvidersRepository(store.context)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Persistence.swift
|
// VPNPersistence.swift
|
||||||
// Passepartout
|
// Passepartout
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 4/7/22.
|
// Created by Davide De Rosa on 4/7/22.
|
||||||
|
@ -28,25 +28,30 @@ import Foundation
|
||||||
import PassepartoutCore
|
import PassepartoutCore
|
||||||
import PassepartoutVPN
|
import PassepartoutVPN
|
||||||
|
|
||||||
extension PassepartoutPersistence {
|
public final class VPNPersistence {
|
||||||
private static let profilesDataModel: NSManagedObjectModel = {
|
private static let dataModel: NSManagedObjectModel = {
|
||||||
guard let model = NSManagedObjectModel.mergedModel(from: [.module]) else {
|
guard let model = NSManagedObjectModel.mergedModel(from: [.module]) else {
|
||||||
fatalError("Could not load PassepartoutProfiles model")
|
fatalError("Could not load PassepartoutProfiles model")
|
||||||
}
|
}
|
||||||
return model
|
return model
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public static func profilesStore(withName containerName: String, cloudKit: Bool, author: String?) -> CoreDataPersistentStore {
|
private let store: CoreDataPersistentStore
|
||||||
.init(
|
|
||||||
|
public var containerURLs: [URL]? {
|
||||||
|
store.containerURLs
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(withName containerName: String, cloudKit: Bool, author: String?) {
|
||||||
|
store = .init(
|
||||||
withName: containerName,
|
withName: containerName,
|
||||||
model: profilesDataModel,
|
model: Self.dataModel,
|
||||||
cloudKit: cloudKit,
|
cloudKit: cloudKit,
|
||||||
author: author
|
author: author
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
extension PassepartoutPersistence {
|
public func profileRepository() -> ProfileRepository {
|
||||||
public static func profileRepository(_ store: CoreDataPersistentStore) -> ProfileRepository {
|
|
||||||
CDProfileRepository(store.context)
|
CDProfileRepository(store.context)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,7 @@ import PassepartoutProviders
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
final class ProvidersTests: XCTestCase {
|
final class ProvidersTests: XCTestCase {
|
||||||
private var persistence: CoreDataPersistentStore!
|
private var persistence: ProvidersPersistence!
|
||||||
|
|
||||||
private var manager: ProviderManager!
|
private var manager: ProviderManager!
|
||||||
|
|
||||||
|
@ -39,16 +39,16 @@ final class ProvidersTests: XCTestCase {
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
let model = NSManagedObjectModel.mergedModel(from: [.module])!
|
let model = NSManagedObjectModel.mergedModel(from: [.module])!
|
||||||
persistence = CoreDataPersistentStore(withName: "ProvidersTests", model: model, cloudKit: false, author: nil)
|
persistence = ProvidersPersistence(withName: "ProvidersTests", cloudKit: false, author: nil)
|
||||||
|
|
||||||
let remoteStrategy = APIRemoteProvidersStrategy(
|
let remoteStrategy = APIRemoteProvidersStrategy(
|
||||||
appBuild: 10000,
|
appBuild: 10000,
|
||||||
bundleServices: APIWebServices.bundledServices(withVersion: "v5"),
|
bundleServices: APIWebServices.bundledServices(withVersion: "v5"),
|
||||||
remoteServices: APIWebServices("v5", URL(string: "https://passepartoutvpn.app/api/")!, timeout: nil),
|
remoteServices: APIWebServices("v5", URL(string: "https://passepartoutvpn.app/api/")!, timeout: nil),
|
||||||
webServicesRepository: PassepartoutPersistence.webServicesRepository(persistence)
|
webServicesRepository: persistence.webServicesRepository()
|
||||||
)
|
)
|
||||||
manager = ProviderManager(
|
manager = ProviderManager(
|
||||||
localProvidersRepository: PassepartoutPersistence.localProvidersRepository(persistence),
|
localProvidersRepository: persistence.localProvidersRepository(),
|
||||||
remoteProvidersStrategy: remoteStrategy
|
remoteProvidersStrategy: remoteStrategy
|
||||||
)
|
)
|
||||||
// persistence.truncate()
|
// persistence.truncate()
|
||||||
|
|
Loading…
Reference in New Issue