强制 NSPersistentContainer 更改核心数据
Forcing NSPersistentContainer change Core Data
我刚刚在我的应用程序中添加了用户切换云同步的选项,我在 "useCloudSync" 下的 UserDefaults 中保存了用户是否想要使用 iCloud 同步。当应用程序 运行s 加载我的 persistentContainer 时:
class CoreDataManager {
static let sharedManager = CoreDataManager()
private init() {}
lazy var persistentContainer: NSPersistentContainer = {
var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
let description = containerToUse!.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
guard let container = containerToUse, let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
...
return container
}
}
当用户使用 UISwitcher 切换云同步时,我更改了 UserDefaults 中 "useCloudSyc" 的值,但应用程序不使用 NSPersistentCloudKitContainer
直到他们强行关闭应用程序并重新运行 再说一遍。我希望容器在用户切换开关以开始从 iCloud 加载数据时立即更改。
当用户切换 "CloudSync" 时,如何在 NSPersistentCloudKitContainer
之间切换?
这是可能的方法
extension UserDefaults { // helper key path for observing
@objc dynamic var useCloudSync: Bool {
return bool(forKey: "useCloudSync")
}
}
class CoreDataManager {
static let sharedManager = CoreDataManager()
private var observer: NSKeyValueObservation?
private init() {
}
lazy var persistentContainer: NSPersistentContainer = {
setupContainer()
}()
private func setupContainer() -> NSPersistentContainer {
if nil == observer {
// setup observe for defults changed
observer = UserDefaults.standard.observe(\.useCloudSync) { [weak self] (_, _) in
try? self?.persistentContainer.viewContext.save() // save anything pending
if let newContainer = self?.setupContainer() {
self?.persistentContainer = newContainer
}
}
}
let useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
let description = containerToUse!.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
guard let container = containerToUse, let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores { (storeDescription, error) in
// ...
}
return container
}
}
我刚刚在我的应用程序中添加了用户切换云同步的选项,我在 "useCloudSync" 下的 UserDefaults 中保存了用户是否想要使用 iCloud 同步。当应用程序 运行s 加载我的 persistentContainer 时:
class CoreDataManager {
static let sharedManager = CoreDataManager()
private init() {}
lazy var persistentContainer: NSPersistentContainer = {
var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
let description = containerToUse!.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
guard let container = containerToUse, let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
...
return container
}
}
当用户使用 UISwitcher 切换云同步时,我更改了 UserDefaults 中 "useCloudSyc" 的值,但应用程序不使用 NSPersistentCloudKitContainer
直到他们强行关闭应用程序并重新运行 再说一遍。我希望容器在用户切换开关以开始从 iCloud 加载数据时立即更改。
当用户切换 "CloudSync" 时,如何在 NSPersistentCloudKitContainer
之间切换?
这是可能的方法
extension UserDefaults { // helper key path for observing
@objc dynamic var useCloudSync: Bool {
return bool(forKey: "useCloudSync")
}
}
class CoreDataManager {
static let sharedManager = CoreDataManager()
private var observer: NSKeyValueObservation?
private init() {
}
lazy var persistentContainer: NSPersistentContainer = {
setupContainer()
}()
private func setupContainer() -> NSPersistentContainer {
if nil == observer {
// setup observe for defults changed
observer = UserDefaults.standard.observe(\.useCloudSync) { [weak self] (_, _) in
try? self?.persistentContainer.viewContext.save() // save anything pending
if let newContainer = self?.setupContainer() {
self?.persistentContainer = newContainer
}
}
}
let useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
let description = containerToUse!.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
guard let container = containerToUse, let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores { (storeDescription, error) in
// ...
}
return container
}
}