本文初次使用MarkDown语法撰写
未完待续
阅读该文章前,可以先行阅读以下几篇博客,对基础知识进行了解
CoreData使用
环境搭建
1、项目创建时勾选CoreData选项
同时在启动类AppDelegate
类中会生成如下代码:
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreDataDemo")
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)")
}
}
}
同时生成文件”.xcdatamodeld“:
点击 ”Add Entity“创建一个实体类:
2、项目创建时未勾选CoreData选项
3、关联属性配置
(1)
To Many:表示该属性为一对多(一个用户对应多辆车)
To One:表示一对一(一个用户只能有一辆车)
(2)
No Action:当A被删除时,B对象不变,但会指向一个不存在的对象,一般不建议使用;
Nullify(作废):当A对象被删除时,B对象指向的A对象会置为空,如果A与B的关系式一对多,则是A对象从B容器中移除;
Cascade(级联):当A对象被删除时,A对象指向的B对象也会被删除;
Deny(拒绝):当删除指向对象B存在的A对象时,操作将会被拒绝;
4、生成实体类代码
根据以上操作可以生成继承自
NSManagedObject
的Class
在只有一个Entity
时,生成的类并没有报错,但是写该Demo有多级属性关联时,生成的实例类报错了:
修改所有Entity
右侧配置项的“Codegen”,由Class Definition
更改为Manual/None
编译后通过(此处被坑很长时间):
代码
5、管理类设计
在创建工程时,代码自动创建于AppDelegate
文件中,这会拖慢APP的启动速度,所以将其单独设计成一个单例管理类比较合适(需要导入头文件CoreData
):
public class KYCoreData{
var modelName: String = "KYTask"
private static let instance: KYCoreData = KYCoreData()
/// 获取单例
class func shared(modelName: String) -> KYCoreData {
instance.modelName = modelName
return instance
}
class func shared() -> KYCoreData {
assert(instance.modelName != "", "modelName不能为空!!!")
return self.shared(modelName: KYCoreData.instance.modelName)
}
@available(iOS 10.0, *)
lazy var storeContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: KYCoreData.instance.modelName)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
debugPrint("Unclear error\(error)")
}
})
return container
}()
@available(iOS 10.0, *)
lazy var managedContext: NSManagedObjectContext = {
return self.storeContainer.viewContext
}()
func saveContext() {
if #available(iOS 10.0, *) {
guard managedContext.hasChanges else { return }
} else {
// Fallback on earlier versions
}
do {
if #available(iOS 10.0, *) {
try managedContext.save()
} else {
// Fallback on earlier versions
}
} catch let error as NSError {
debugPrint("Unclear error\(error)")
}
}
}
6、增、删、改、查操作
(1)增
/// 插入任务
class func insert(task: KYTaskModel) -> Bool {
var isSuccess = true
// 步骤一:获取总代理和托管对象总管
let managedContext = KYCoreData.shared().managedContext
// 步骤二:建立一个entity
let entity = NSEntityDescription.entity(forEntityName: "KYTask", in: managedContext)
let event = NSManagedObject(entity: entity!, insertInto: managedContext)
// 步骤三:保存文本框中的值到person
event.setValue(task.taskTitle, forKey: "taskTitle")
event.setValue(task.taskDesc, forKey: "taskDesc")
event.setValue(task.taskDate, forKey: "taskDate")
event.setValue(task.remindTime, forKey: "remindTime")
event.setValue(task.isComplete, forKey: "isComplete")
event.setValue(task.taskLevel, forKey: "taskLevel")
event.setValue(task.taskID, forKey: "taskID")
// 步骤四:保存entity到托管对象中。如果保存失败,进行处理
do {
try managedContext.save()
} catch {
isSuccess = false
fatalError("无法保存")
}
return isSuccess
}
(2)删
/// 删除一条任务
class func deleteTheTask(withTaskID taskID: Int64) -> Bool {
var isSuccess = true
//获取数据上下文对象
let managedContext = KYCoreData.shared().managedContext
//声明数据的请求,声明一个实体结构
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "KYTask")
//查询条件
request.predicate = NSPredicate.init(format: "taskID == %d", taskID)
// 异步请求由两部分组成:普通的request和completion handler
let async = NSAsynchronousFetchRequest(fetchRequest: request) {
(result) in
if (result.finalResult != nil) {
let fetchObj = result.finalResult! as! [KYTask]
for obj: KYTask in fetchObj {
managedContext.delete(obj)
//KYCoreData.shared().saveContext()
}
KYCoreData.shared().saveContext()
}
}
do {
try managedContext.execute(async)
} catch {
isSuccess = false
print(error)
}
return isSuccess
}
(3)改
/// 修改任务信息
class func updateTaskInfo(task: KYTaskModel) -> Bool {
var isSuccess = true
let context = KYCoreData.shared().managedContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "KYTask")
request.predicate = NSPredicate(format: "taskID = %d", task.taskID)
do {
let result = try context.fetch(request) as! [KYTask]
result.forEach({ (event) in
event.setTask(taskModel: task)
})
if context.hasChanges {
try context.save()
}
} catch {
isSuccess = false
print(error)
}
return isSuccess
}
(4)查
/// 根据日期查询任务列表
class func queryAllTask(withDate date: String) -> [KYTaskModel] {
let resultArr = NSMutableArray()
// 步骤一:获取总代理和托管对象总管
let managedObectContext = KYCoreData.shared().managedContext
// 步骤二:建立一个获取的请求
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "KYTask")
fetchRequest.predicate = NSPredicate(format: "taskDate = %@", date)
//fetchRequest.resultType = .managedObjectResultType
// 排序,ascending: true 升序,否则为降序
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "taskLevel", ascending: false), NSSortDescriptor(key: "remindTime", ascending: true)]
// 步骤三:执行请求
do {
let fetchedResults = try managedObectContext.fetch(fetchRequest) as? [NSManagedObject]
if let results = fetchedResults {
for model: NSManagedObject in results {
let task = KYTaskModel(task: model as! KYTask)
//print("queryAllTask 查询到的数据title ----> %@, 等级: %@d", task.taskTitle, task.taskLevel)
resultArr.add(task)
}
}
} catch {
fatalError("获取失败")
}
return resultArr as! [KYTaskModel]
}