Swift实现CoreData存储数据

关键时刻,第一时间送达!

之前写过一篇介绍iOS数据存储方法的文章,包含:FMDB,SQLite3 ,Core Data,Plist,偏好设置,归档。

链接:https://www.jianshu.com/p/e88880be794f

本文则是介绍Swift中CoreData的基本使用。

文中示例代码GitHub地址:Demo(https://github.com/remember17/CoreDataSwiftDemo)

coredata.gif

目录

一、 图形化创建模型

二、 手动创建模型并实现AppDelegate中的代码

三、 创建并实现CoreDataManager

一、图形化创建模型(这一小节的内容我的另一篇文(https://www.jianshu.com/p/e88880be794f)中也有,如已经熟悉,或想要直接手动创建模型,可以直接看第二小节正式进入Swift)

创建项目的时候,勾选下图中的Use Core Data选项,工程中会自动创建一个数据模型文件。当然,你也可以在开发中自己手动创建。

自动创建模型文件

下图就是自动创建出来的文件

创建出来的文件

如果没有勾选,也可以在这里手动创建。

手动创建

点击Add Entity之后,相当一张数据表。表的名称自己在上方定义,注意首字母要大写。

在界面中还可以为数据实体添加属性和关联属性。

创建一个数据表

Core Data属性支持的数据类型如下

数据类型

编译之后,Xcode会自动生成Person的实体代码文件,并且文件不会显示在工程中,如果下图中右侧Codegen选择Manual/None,则Xcode就不会自动生成代码,我们可以自己手动生成。

6.png

手动生成实体类代码,选中CoreDataTest.xcdatamodeld文件,然后在Mac菜单栏中选择Editor,如下图所示。一路Next就可以了。

如果没有选择Manual/None,依然进行手动创建的话,则会与系统自动创建的文件发生冲突,这点需要注意。

你也可以不要选择Manual/None,直接使用系统创建好的NSManagedObject,同样会有4个文件,只是在工程中是看不到的。

手动创建NSManagedObject

Swift中手动创建出来的是这样2个文件

还要注意编程语言的选择,Swift或OC

编程语言

二、手动创建模型并实现AppDelegate中的代码

讲道理,这一节应该是Core Data堆栈的介绍与使用,不过由于之前的文章中已经有了,这里就不啰嗦了,我们直接上图和代码。

1.如下图所示,创建模型,我这里直接创建一个命名为Model的模型。

创建模型.png

2.创建Person表,两个属性name和age,注意右侧的Codegen我们这里选择Class Definition,然后直接Command+B编译代码,Xcode会自动帮我们生成Person+CoreDataClass.swift和Person+CoreDataProperties.swift文件

创建数据表.png

3.配置AppDelegate中的代码,首先导入CoreData头文件,然后懒加载NSManagedObjectModel

注意modelURL中填写的是模型文件的名字,并且后缀填写momd

import CoreData

lazy var managedObjectModel: NSManagedObjectModel = {

let managedObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!)

return managedObjectModel!

}()

4.懒加载持久化存储协调器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 {

// Report any error we got.

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 = {

return documentDir!

}()

5.懒加载NSManagedObjectContext

lazy var context: NSManagedObjectContext = {

let context = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)

context.persistentStoreCoordinator = persistentStoreCoordinator

return context

}()

三、创建并实现CoreDataManager

我一般是把数据存储方法封装到一个CoreDataManager中,这样在以后的使用中比较方便。当然,你也可以根据自己的需求灵活运用。

1.创建一个继承自NSObject的CoreDataManager.swfit文件,并且import CoreData

创建CoreDataManager

2.实现CoreDataManager的单例,并且拿到AppDelegate中刚才懒加载的NSManagedObjectContext

swift中创建单例比较方便,直接static let shared = CoreDataManager()

// 单例

static let shared = CoreDataManager()

// 拿到AppDelegate中创建好了的NSManagedObjectContext

lazy var context: NSManagedObjectContext = {

let context = ((UIApplication.shared.delegate) as! AppDelegate).context

return context

}()

3.实现更新数据的方法

除了查询数据,其余对数据进行增删改的时候,都别忘记调用这个方法,只有这个方法执行ok,才算增删改完成。

// 更新数据

private func saveContext() {

do {

try context.save()

} catch {

let nserror = error as NSError

fatalError("Unresolved error (nserror), (nserror.userInfo)")

}

}

4.增加数据(保存数据)

首先运用NSEntityDescription创建出person

然后为person赋值,最终调用saveContext()方法保存数据

// 增加数据

func savePersonWith(name: String, age: Int16) {

let person = NSEntityDescription.insertNewObject(forEntityName: "Person", into: context) as! Person

person.name = name

person.age = age

saveContext()

}

5.获取所有数据

如果是通过系统自动生成的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();

}

}

6.获取特定条件的数据

可以利用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();

}

}

7.修改数据

首先获取到想要修改的数据

然后循环修改就可以了

最后别忘记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 = newName

person.age = newAge

}

} catch {

fatalError();

}

saveContext()

}

8.根据条件删除数据

与修改数据一样,首先拿到符合删除条件的数据

循环调用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()

}

9.删除所有数据

获取所有数据

循环删除

save

// 删除所有数据

func deleteAllPerson() {

// 这里直接调用上面获取所有数据的方法

let result = getAllPerson()

// 循环删除所有数据

for person in result {

context.delete(person)

}

saveContext()

}

后记

本文运用一个简单的示例来说明swift中如何使用CoreData,更多用法或注意事项就不一一列举了。

本文Demo:

https://github.com/remember17/CoreDataSwiftDemo

作者GitHub:

https://github.com/remember17

作者:remember17

https://www.jianshu.com/p/e4c106015005

程序员共读整理发布,转载请联系作者授权

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180219B0I1QI00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券