之前写过一篇介绍iOS数据存储方法的文章,包含:FMDB,SQLite3 ,Core Data,Plist,偏好设置,归档。 链接:www.jianshu.com/p/e88880be7…
本文则是介绍Swift中CoreData的基本使用。 文中示例代码GitHub地址:Demo
目录 一、 图形化创建模型 二、 手动创建模型并实现AppDelegate中的代码 三、 创建并实现CoreDataManager
一、图形化创建模型(这一小节的内容我的另一篇文中也有,如已经熟悉,或想要直接手动创建模型,可以直接看第二小节正式进入Swift) 创建项目的时候,勾选下图中的Use Core Data选项,工程中会自动创建一个数据模型文件。当然,你也可以在开发中自己手动创建。
下图就是自动创建出来的文件
如果没有勾选,也可以在这里手动创建。
点击Add Entity之后,相当一张数据表。表的名称自己在上方定义,注意首字母要大写。 在界面中还可以为数据实体添加属性和关联属性。
Core Data属性支持的数据类型如下
编译之后,Xcode会自动生成Person的实体代码文件,并且文件不会显示在工程中,如果下图中右侧Codegen选择Manual/None,则Xcode就不会自动生成代码,我们可以自己手动生成。
手动生成实体类代码,选中CoreDataTest.xcdatamodeld文件,然后在Mac菜单栏中选择Editor,如下图所示。一路Next就可以了。 如果没有选择Manual/None,依然进行手动创建的话,则会与系统自动创建的文件发生冲突,这点需要注意。 你也可以不要选择Manual/None,直接使用系统创建好的NSManagedObject,同样会有4个文件,只是在工程中是看不到的。
Swift中手动创建出来的是这样2个文件
还要注意编程语言的选择,Swift或OC
二、手动创建模型并实现AppDelegate中的代码 讲道理,这一节应该是Core Data堆栈的介绍与使用,不过由于之前的文章中已经有了,这里就不啰嗦了,我们直接上图和代码。
如下图所示,创建模型,我这里直接创建一个命名为Model的模型。
创建Person表,两个属性name和age,注意右侧的Codegen我们这里选择Class Definition,然后直接Command+B编译代码,Xcode会自动帮我们生成Person+CoreDataClass.swift和Person+CoreDataProperties.swift文件
配置AppDelegate中的代码,首先导入CoreData头文件,然后懒加载NSManagedObjectModel 注意modelURL中填写的是模型文件的名字,并且后缀填写momd
import CoreDatalazy var managedObjectModel:
NSManagedObjectModel = {let modelURL = Bundle.main.url(forResource:
"Model" , withExtension:
"momd" )let managedObjectModel =
NSManagedObjectModel .init(contentsOf: modelURL!)
return managedObjectModel!}()
复制代码 懒加载持久化存储协调器NSPersistentStoreCoordinator sqliteURL是sqlite文件的路径 documentDir是后面加载好了的Document路径 lazy var persistentStoreCoordinator:
NSPersistentStoreCoordinator = {let persistentStoreCoordinator =
NSPersistentStoreCoordinator .init(managedObjectModel: managedObjectModel)let sqliteURL = documentDir.appendingPathComponent(
"Model.sqlite" )let options = [
NSMigratePersistentStoresAutomaticallyOption :
true ,
NSInferMappingModelAutomaticallyOption :
true ]var failureReason =
"There was an error creating or loading the application's saved data." do {try persistentStoreCoordinator.addPersistentStore(ofType:
NSSQLiteStoreType , configurationName:
nil , at: sqliteURL, options: options)} catch {var dict = [String: Any]()dict[
NSLocalizedDescriptionKey ] =
"Failed to initialize the application's saved data" as Any?dict[
NSLocalizedFailureReasonErrorKey ] = failureReason as Any?dict[
NSUnderlyingErrorKey ] = error as
NSError let wrappedError =
NSError (domain:
"YOUR_ERROR_DOMAIN" , code:
6666 , userInfo: dict)print(
"Unresolved error \(wrappedError), \(wrappedError.userInfo)" )abort()}
return persistentStoreCoordinator}()lazy var documentDir: URL = {let documentDir = FileManager.default.urls(
for : FileManager.SearchPathDirectory.documentDirectory,
in : FileManager.SearchPathDomainMask.userDomainMask).first
return documentDir!}()
复制代码 懒加载NSManagedObjectContext lazy var context:
NSManagedObjectContext = {let context =
NSManagedObjectContext .init(concurrencyType:
NSManagedObjectContextConcurrencyType .mainQueueConcurrencyType)context.persistentStoreCoordinator = persistentStoreCoordinator
return context}()
复制代码 三、创建并实现CoreDataManager 我一般是把数据存储方法封装到一个CoreDataManager中,这样在以后的使用中比较方便。当然,你也可以根据自己的需求灵活运用。
创建一个继承自NSObject的CoreDataManager.swfit文件,并且import CoreData
实现CoreDataManager的单例,并且拿到AppDelegate中刚才懒加载的NSManagedObjectContext
swift中创建单例比较方便,直接static let shared = CoreDataManager()
static let shared = CoreDataManager()lazy var context:
NSManagedObjectContext = {let context = ((
UIApplication .shared.delegate) as! AppDelegate).context
return context}()
复制代码 实现更新数据的方法 除了查询数据,其余对数据进行增删改的时候,都别忘记调用这个方法,只有这个方法执行ok,才算增删改完成。
private func saveContext() {
do {try context.save()} catch {let nserror = error as
NSError fatalError(
"Unresolved error \(nserror), \(nserror.userInfo)" )}}
复制代码 增加数据(保存数据) 首先运用NSEntityDescription创建出person 然后为person赋值,最终调用saveContext()方法保存数据 func savePersonWith(name: String, age: Int16) {let person =
NSEntityDescription .insertNewObject(forEntityName:
"Person" , into: context) as! Personperson.name = nameperson.age = agesaveContext()}
复制代码 获取所有数据 如果是通过系统自动生成的CoreData文件,Person会自带一个fetchRequest()的方法,我们可以直接通过Person.fetchRequest()的方式拿到person的NSFetchRequest对象 然后通过context的fetch(fetchRequest)方法拿到数据数组 func getAllPerson() -> [Person] {let fetchRequest:
NSFetchRequest = Person.fetchRequest()
do {let result = try context.fetch(fetchRequest)
return result} catch {fatalError();}}
复制代码 获取特定条件的数据 可以利用NSPredicate来过滤出符合一定条件的数据 而NSFetchRequest中有predicate这样一个属性 func getPersonWith(name: String) -> [Person] {let fetchRequest:
NSFetchRequest = Person.fetchRequest()fetchRequest.predicate =
NSPredicate (format:
"name == %@" , name)
do {let result: [Person] = try context.fetch(fetchRequest)
return result} catch {fatalError();}}
复制代码 修改数据 首先获取到想要修改的数据 然后循环修改就可以了 最后别忘记save func changePersonWith(name: String, newName: String, newAge: Int16) {let fetchRequest:
NSFetchRequest = Person.fetchRequest()fetchRequest.predicate =
NSPredicate (format:
"name == %@" , name)
do {let result = try context.fetch(fetchRequest)
for person
in result {person.name = newNameperson.age = newAge}} catch {fatalError();}saveContext()}
复制代码 根据条件删除数据 与修改数据一样,首先拿到符合删除条件的数据 循环调用context的delete()方法就可以了 最后别忘记save func deleteWith(name: String) {let fetchRequest:
NSFetchRequest = Person.fetchRequest()fetchRequest.predicate =
NSPredicate (format:
"name == %@" , name)
do {let result = try context.fetch(fetchRequest)
for person
in result {context.delete(person)}} catch {fatalError();}saveContext()}
复制代码 删除所有数据 func deleteAllPerson() {let result = getAllPerson()
for person
in result {context.delete(person)}saveContext()}
复制代码 后记 本文运用一个简单的示例来说明swift中如何使用CoreData,更多用法或注意事项就不一一列举了。
本文Demo:github.com/remember17/… 作者GitHub:github.com/remember17
总结
以上是生活随笔 为你收集整理的Swift实现CoreData存储数据 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔 网站内容还不错,欢迎将生活随笔 推荐给好友。