如何在CoreData中創(chuàng)建一個Model
假設(shè)現(xiàn)在需要創(chuàng)建一個Robot的類们何,里面有基本數(shù)據(jù)類型id
和name
屬性,還有另外一個自定義RobotArm的屬性arm
, 那么該如何在CoreData里面使用呢冤竹?
Class Robot: NSManagedObject {
@NSManaged public var id: Int16
@NSManaged public var name: String?
@NSManaged public var arm: RobotArm?
}
1. 首先創(chuàng)建一個Robot Entity
image.png
image.png
會看到側(cè)邊欄有Codegen Options選項(xiàng)
image.png
Q&A 這些選項(xiàng)的區(qū)別是什么茬射?
Options | Meaning |
---|---|
Manual/None | iOS之前是手動創(chuàng)建和維護(hù) NSManagedObject 子類的文件 |
Class Definition | 使用了這個選項(xiàng)鹦蠕,不需要創(chuàng)建對應(yīng)類的file躲株,編譯完就能使用這個類 |
Category/Extension | 使用類別/擴(kuò)展選項(xiàng)片部,可以完全控制類文件,同時繼續(xù)自動生成屬性文件以使其與模型編輯器保持同步档悠。 |
詳情可以看官方文檔: Apple Document
簡單點(diǎn)說:
- 選擇Manual/None就需要手動去創(chuàng)建對應(yīng)的類文件(
Robot+CoreDataClass
和Robot+CoreDataProperties
); - 選擇Class Definition會在編譯時生成這兩個文件望浩,不需要自己定義對應(yīng)的類型
- 選擇Category/Extension,在編譯時只會默認(rèn)生成
Robot+CoreDataProperties
文件典挑,需要手動創(chuàng)建Robot+CoreDataClass
定義該類型
Q&A 如果不是選中Class Definition,選中了Manual/None拙寡,怎么手動創(chuàng)建對應(yīng)Model類的文件肆糕?
A: Xcode有配置的選項(xiàng) ??
image.png
就會生成兩個文件 ??
image.png
如何創(chuàng)建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) )
}
}
怎么取出已經(jīng)保存的數(shù)據(jù)?
- 生成的Robot類里面已經(jīng)生成了創(chuàng)建fetchRequest方法诚啃,可以直接拿到request
- sort 屬性是可以對結(jié)果進(jìn)行排序
// 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")
}
}
}
按照輸出結(jié)果可以得到順序是 Robot 1淮摔, 然后才是Robot
如何進(jìn)行debug?
上面用request去獲取數(shù)據(jù)是其中一種方式,那如果獲取不到數(shù)據(jù)始赎,到底是保存出了問題還是獲取出了問題和橙,怎么判斷是不是保存的時候出了問題?
首先要拿到sqlite的路徑
NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
- 在輸出的路徑下找到sqlite文件
image.png
- 可以用 DB Brower for SQLite 軟件打開极阅,軟件下載 【傳送門??】
打開可以看到數(shù)據(jù)庫里面有幾個表胃碾,忽略Z
的前綴,可以看到Robot 和 RobotArm 表筋搏,打開就可以看到數(shù)據(jù)是否保存仆百。
image.png
id / arm / name 屬性已經(jīng)保存了數(shù)據(jù),ZARM數(shù)據(jù)是 1
,就是指向另外一張表ZROBOT 的對象1
.
Robot 表
image.png
RobotArm 表
image.png
其他內(nèi)容:
關(guān)于繼承關(guān)系
image.png
關(guān)于更新已有Model屬性
- 添加一個Model Version
- 更新model
- 設(shè)置current version
image.png
image.png
這個時候如果更新的Model類的Codegen Options選項(xiàng)是Class Definition
或者Category/Extension
, 則不需要去更新什么文件奔脐;
如果是Manual/None
, 并且文件中沒有其他的邏輯俄周,可以刪除了,重新再創(chuàng)建一次髓迎,或者直接添加屬性在Robot+CoreDataProperties
文件峦朗。