我创建了一个单例课程来管理我的核心数据:
class CoreDataManager {
static let sharedManager = CoreDataManager()
private init() {}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "MyContainer")
if Globals.profileNumber != 0 {
let alternateURL = NSPersistentContainer.defaultDirectoryURL()
let storeURL = alternateURL.appendingPathComponent("\(Globals.profileNumber)MyContainer.sqlite")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
container.persistentStoreDescriptions = [storeDescription]
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
但是稍后如何在应用程序中更改persistentContainer
指向的存储区?
例如,用户加载应用程序,登录并加载默认的sqlite文件。然后,用户切换到另一个用户帐户,该帐户应“关闭”当前数据库,然后persistentContainer
需要加载其他商店?
答案 0 :(得分:2)
如klaudas提供的链接中所述,将实体与用户建立关系的一个堆栈作为一个很好的选择。
如果您希望拥有单独的商店,则可以尝试以下操作:
class CoreDataManager {
// The rest of your class...
private(set) var persistentContainer: NSPersistentContainer?
func setupNewPersistentContainer(completionHandler: @escaping (_ success: Bool) -> Void) {
let container = NSPersistentContainer(name: "MyContainer")
// You should also handle the case where profileNumber == 0 and your store URL can't be constructed.
if Globals.profileNumber != 0 {
let alternateURL = NSPersistentContainer.defaultDirectoryURL()
let storeURL = alternateURL.appendingPathComponent("\(Globals.profileNumber)MyContainer.sqlite")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
container.persistentStoreDescriptions = [storeDescription]
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Handle the error.
fatalError("Unresolved error \(error), \(error.userInfo)")
}
let success: Bool = error == nil
completionHandler(success)
})
persistentContainer = container
}
// The rest of your class...
}
基本上,您将容器设置逻辑放在一个函数中,该函数在您第一次初始化堆栈并在以后切换帐户时调用。您可以调整类以使persistentContainer成为非可选,或添加一个标志来跟踪商店是否成功加载。
尽管有一些注意事项:
使用这种方法,您还需要刷新保存在内存中的所有获取的结果控制器和托管对象(因为它们的持久性存储不再可访问)。最简单的方法是在切换时重置整个UI。
设置新容器时,请等待完成处理程序,然后再继续进行帐户切换流程。
如果对托管对象有任何引用,则可以通过选中object.managedObjectContext?.persistentStoreCoordinator == context.persistentStoreCoordinator
来查看它们在上下文中是否有效。