设置Core Data Stack
如果我们在项目设置期间选中了“Use Core Data”复选框,则Xcode会将“CoreData”堆栈的代码放入应用程序委托中。这是我不喜欢的事情,我们不会因Core Data堆栈的设置而使应用程序代表混乱。
文章推荐
推荐代码
相反,我们将创建一个单独的类,负责设置和管理核心数据堆栈。创建一个新组并将其命名为“Managers”。在“Managers”组中创建一个新的Swift文件,并将其命名为CoreDataManager.swift。 CoreDataManager类负责应用程序的Core Data堆栈。
将Foundation框架的导入语句替换为Core Data框架的导入语句。
import CoreData
接下来,我们定义类本身。请注意,我们将CoreDataManager类标记为final。它不打算被子类化。
import CoreData
final class CoreDataManager {
}
我们要提供给Core Data Manager的唯一信息是数据模型的名称。我们首先为数据模型的名称创建一个属性。该属性的类型为String。
import CoreData
final class CoreDataManager {
// MARK: - Properties
private let modelName: String
}
类的指定初始值设定项接受数据模型的名称作为参数。
import CoreData
final class CoreDataManager {
// MARK: - Properties
private let modelName: String
// MARK: - Initialization
init(modelName: String) {
self.modelName = modelName
}
}
请注意我们需要实现Core Data Stack的三个对象:
- a managed object model
- a managed object context
- a persistent store coordinator
首先,为每个对象创建一个lazy属性。这些属性被标记为私有。但是请注意,我们仅将managedObjectContext属性的设置器标记为私有。需要访问核心数据堆栈的其他对象应该可以访问核心数据管理器的托管对象上下文。请记住,托管对象上下文是我们最常使用的对象。这是核
private(set) lazy var managedObjectContext: NSManagedObjectContext ={}()
private lazy var managedObjectModel: NSManagedObjectModel = {}()
private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {}()
Managed Object Context
让我们从实现ManagedObjectContext属性开始。我们通过调用其指定的初始化程序init(concurrencyType :)来初始化NSManagedObjectContext类的实例。此初始化程序接受类型为NSManagedObjectContextConcurrencyType的参数。我们传入mainQueueConcurrencyType,这意味着托管对象上下文与应用程序的主队列或主线程关联。我们将在本书后面的内容中详细了解线程。现在不用担心。
// Initialize Managed Object Context
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
请记住,每个父级受管对象上下文都引用了核心数据堆栈的持久性存储协调器。这意味着我们需要设置托管对象上下文的persistentStoreCoordinator属性。
// Configure Managed Object Context
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
并且我们从闭包中返回托管对象上下文。
private(set) lazy var managedObjectContext: NSManagedObjectContext ={
// Initialize Managed Object Context
let managedObjectContext =NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
// Configure Managed Object Context
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
Managed Object Model
初始化管理对象模型很容易。我们向应用程序bundle索要数据模型的URL,然后使用该URL实例化NSManagedObjectModel类的实例。
// Fetch Model URL
guard let modelURL = Bundle.main.url(forResource: self.modelName, withExtension: "momd") else {
fatalError("Unable to Find Data Model")
}
// Initialize Managed Object Model
guard let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL) else {
10 fatalError("Unable to Load Data Model")
}
我们从闭包中返回managed object model 。
private lazy var managedObjectModel: NSManagedObjectModel = {
// Fetch Model URL
guard let modelURL = Bundle.main.url(forResource: self.modelName , withExtension: "momd") else {
fatalError("Unable to Find Data Model")
}
// Initialize Managed Object Model
guard let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Unable to Load Data Model")
}
return managedObjectModel
}()
Persistent Store Coordinator
难题的最后一部分是持久存储协调员。这有点复杂。我们首先使用托管对象模型实例化NSPersistentStoreCoordinator类的实例。但这只是第一步。
// Initialize Persistent Store Coordinator
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
只有将持久性存储添加到持久性存储协调器后,Core Data堆栈才起作用。我们首先为持久性存储创建URL。有几个存储永久存储的位置。在此示例中,我们将持久性存储存储在应用程序沙箱的“文档”目录中。但是您也可以将其存储在Library目录中。
我们将sqlite附加到数据模型的名称上,因为我们将使用SQLite数据库作为持久性存储。请记住,Core Data开箱即用地支持SQLite数据库。
// Helpers
let fileManager = FileManager.default
let storeName = "\(self.modelName).sqlite"
// URL Documents Directory
let documentsDirectoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// URL Persistent Store
let persistentStoreURL = documentsDirectoryURL.appendingPathComponent(storeName)
由于添加持久性存储可能会失败,因此我们需要在do-catch语句中执行它。要添加持久性存储,我们在持久性存储协调器上调用addPersistentStore(ofType:configurationName:at:options :)。
此方法接受四个参数:
- 持久存储的类型,在此示例中为SQLite
- 可选配置
- 持久性存储的位置
- 选项的可选词典
do {
// Add Persistent Store
let options = [ NSMigratePersistentStoresAutomaticallyOption : true, NSInferMappingModelAutomaticallyOption : true ]
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options : options)
} catch {}
如果持久性存储协调器在我们指定的位置找不到持久性存储,它将为我们创建一个持久性存储。如果在指定位置已经存在一个持久性存储,则将其添加到持久性存储协调器。这意味着永久存储是在用户第一次启动您的应用程序时自动创建的。第二次,Core Data查找持久性存储,在指定位置找到它,然后“将其添加到持久性存储协调器中。该框架为您处理。
在catch子句中,如果操作失败,则将错误输出到控制台。我们从闭包中返回持久性存储协调器。
private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// Initialize Persistent Store Coordinator
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
// Helpers
let fileManager = FileManager.default
let storeName = "\(self.modelName).sqlite"
// URL Documents Directory
let documentsDirectoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
// URL Persistent Store
let persistentStoreURL = documentsDirectoryURL.appendingPathComponent(storeName)
do {
// Add Persistent Store
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: nil)
} catch {
fatalError("Unable to Add Persistent Store")
}
return persistentStoreCoordinator
}()
技术交流
QQ:3365059189
SwiftUI技术交流QQ群:518696470