CoreData/SQLite/FMDBiOS工作生活

CoreData的使用

2019-07-02  本文已影响0人  Grabin
如何在CoreData中创建一个Model

假设现在需要创建一个Robot的类,里面有基本数据类型idname属性,还有另外一个自定义RobotArm的属性arm, 那么该如何在CoreData里面使用呢?

Class Robot: NSManagedObject {
    @NSManaged public var id: Int16
    @NSManaged public var name: String?
    @NSManaged public var arm: RobotArm?
}
1. 首先创建一个Robot Entity



image.png
image.png
会看到侧边栏有Codegen Options选项



image.png
Q&A 这些选项的区别是什么?
Options Meaning
Manual/None iOS之前是手动创建和维护 NSManagedObject 子类的文件
Class Definition 使用了这个选项,不需要创建对应类的file,编译完就能使用这个类
Category/Extension 使用类别/扩展选项,可以完全控制类文件,同时继续自动生成属性文件以使其与模型编辑器保持同步。

详情可以看官方文档: Apple Document

简单点说:
Q&A 如果不是选中Class Definition,选中了Manual/None,怎么手动创建对应Model类的文件?

A: Xcode有配置的选项 👇


image.png


就会生成两个文件 👇


image.png



如何创建Model,并保存在CoreData?
import UIKit
import CoreData

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext

        let robotEntity = NSEntityDescription.entity(forEntityName: "Robot", in: context)
        let robot = Robot(entity: robotEntity!, insertInto: context)
        robot.id = 12138
        robot.name = "I'm a robot!"

        let robotArmEntity = NSEntityDescription.entity(forEntityName: "RobotArm", in: context)
        let robotArm = RobotArm(entity: robotArmEntity!, insertInto: context)
        robotArm.id = 555
        robotArm.numberOfFingers = 10

        robot.arm = robotArm

        do {
            try context.save()
        } catch {
            print("Failed saving")
        }
        
        print(NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) )
    }


}




怎么取出已经保存的数据?
// Fetching models from CoreData
        do {
            let robotsRequest: NSFetchRequest<Robot> = Robot.fetchRequest()
            let sort = NSSortDescriptor(key: "id", ascending: true)
            robotsRequest.sortDescriptors = [sort]
            let robots = try context.fetch(robotsRequest)
            print(robots)
        } catch {
            print("Failed fetching")
        }



完整代码

import UIKit
import CoreData

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        let robotEntity = NSEntityDescription.entity(forEntityName: "Robot", in: context)
        let robot = Robot(entity: robotEntity!, insertInto: context)
        robot.id = 12138
        robot.name = "I'm a robot!"

        let robot1 = Robot(entity: robotEntity!, insertInto: context)
        robot1.id = 110
        robot1.name = "I'm a robot1 !"

        let robotArmEntity = NSEntityDescription.entity(forEntityName: "RobotArm", in: context)
        let robotArm = RobotArm(entity: robotArmEntity!, insertInto: context)
        robotArm.id = 555
        robotArm.numberOfFingers = 10

        robot.arm = robotArm

        do {
            try context.save()
        } catch {
            print("Failed saving")
        }
        
        
        
        print(NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) )
        
        
        // Fetching models from CoreData
        do {
            let robotsRequest: NSFetchRequest<Robot> = Robot.fetchRequest()
            let sort = NSSortDescriptor(key: "id", ascending: true)
            robotsRequest.sortDescriptors = [sort]
            let robots = try context.fetch(robotsRequest)
            print(robots)
        } catch {
            print("Failed fetching")
        }
    }

}


按照输出结果可以得到顺序是 Robot 1, 然后才是Robot

如何进行debug?



上面用request去获取数据是其中一种方式,那如果获取不到数据,到底是保存出了问题还是获取出了问题,怎么判断是不是保存的时候出了问题?

首先要拿到sqlite的路径

NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) 

id / arm / name 属性已经保存了数据,ZARM数据是 1,就是指向另外一张表ZROBOT 的对象1.



Robot 表

image.png
RobotArm 表 image.png




其他内容:



关于继承关系

image.png

关于更新已有Model属性

  1. 添加一个Model Version
  2. 更新model
  3. 设置current version
image.png
image.png



这个时候如果更新的Model类的Codegen Options选项是Class Definition或者Category/Extension, 则不需要去更新什么文件;
如果是Manual/None, 并且文件中没有其他的逻辑,可以删除了,重新再创建一次,或者直接添加属性在Robot+CoreDataProperties文件。

上一篇 下一篇

猜你喜欢

热点阅读