Core Data是用來(lái)將模型對(duì)象持久化儲(chǔ)存的框架偏形,可以保存XML敏储、atomic、SQLite格式的文件丁侄。這里使用SQLite來(lái)舉例惯雳。在你新建一個(gè)工程的時(shí)候,選擇use Core Data鸿摇,Xcode會(huì)幫你做一些準(zhǔn)備工作石景。在這里一共有這么幾個(gè)東西,持久化儲(chǔ)存文件拙吉,持久化儲(chǔ)存協(xié)調(diào)器潮孽,托管對(duì)象模型,托管對(duì)像上下文筷黔。
- 一個(gè)托管對(duì)象模型中會(huì)有多個(gè)實(shí)體恩商,這些實(shí)體可以儲(chǔ)存在不同的持久化儲(chǔ)存文件中
- 一個(gè)持久化儲(chǔ)存協(xié)調(diào)器只能和一個(gè)托管對(duì)象模型相連
- 一個(gè)或多個(gè)托管對(duì)象上下文通過(guò)訪問(wèn)持久化對(duì)象儲(chǔ)存協(xié)調(diào)器來(lái)訪問(wèn)持久化儲(chǔ)存文件
- 程序中操作的就是托管對(duì)象上下文
創(chuàng)建實(shí)體
Xcode會(huì)給你創(chuàng)建一個(gè)CoreDataTest.xcdatamodeld文件,這就是你管理你的對(duì)象的地方必逆,新建實(shí)體怠堪,并在實(shí)體里建立你需要的屬性和關(guān)系等揽乱。
建立好之后就可以讓Xcode幫助你生成每個(gè)實(shí)體對(duì)應(yīng)的類了:Editor -> Create NSManagedObject SubClass。對(duì)應(yīng)每個(gè)實(shí)體這會(huì)生成兩個(gè)Swift文件粟矿,你的每個(gè)實(shí)體在這里都變成了 NSManagedObject的子類凰棉,這也是在代碼中我們使用的類。
托管對(duì)象
在AppDelegate里陌粹,Xcode會(huì)幫你做一些事情:
- 首先它幫你獲取了持久化儲(chǔ)存的目錄撒犀,這也是App一般存數(shù)據(jù)的地方:
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "edu.bupt.exialym.CoreDataTest" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
- 接著將你的模型轉(zhuǎn)換為NSManagedObject類,這里獲取的CoreDataText.momd文件非常重要掏秩,它與你的工程名相對(duì)應(yīng):
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("CoreDataTest", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
持久化儲(chǔ)存協(xié)調(diào)器
持久化儲(chǔ)存器是程序訪問(wèn)持久化儲(chǔ)存的橋梁或舞。
在AppDelegate中,這個(gè)變量Xcode也創(chuàng)建好了:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
在這里蒙幻,定義了與此持久化儲(chǔ)存協(xié)調(diào)器對(duì)應(yīng)的托管對(duì)象模型映凳、持久化儲(chǔ)存文件。
托管對(duì)象上下文
在AppDelegate中邮破,Xcode還定義了托管上下文诈豌,并指向了上面的持久化儲(chǔ)存協(xié)調(diào)器:
lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
當(dāng)托管對(duì)象改變時(shí),需要儲(chǔ)存當(dāng)前的托管對(duì)象上下文抒和,這時(shí)你所做的修改才能保存起來(lái)矫渔,這樣也為撤銷和重做提供了支持。增刪改查摧莽,只有查不需要保存庙洼。這個(gè)方法Xcode也在AppDelegate里生成了:
func saveContext () {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
}
}
}
查
增刪改很大程度上是在查的基礎(chǔ)上完成的
//首先,規(guī)定獲取數(shù)據(jù)的實(shí)體
let request = NSFetchRequest(entityName: "Book")
//配置查詢條件镊辕,如果有需要還可以配置結(jié)果排序
let predicate = NSPredicate(format: "%K == %@", "name", nameText.text!)
request.predicate = predicate
var result:[NSManagedObject] = []
do{
//進(jìn)行查詢油够,結(jié)果是一個(gè)托管對(duì)象數(shù)組
result = try appDelegate.managedObjectContext.executeFetchRequest(request) as! [NSManagedObject]
} catch {}
resultText.text = ""
for item in result {
//用鍵值對(duì)的方式獲取各個(gè)值
resultText.text! += "書名:\(item.valueForKey("name") as! String) 作者:\(item.valueForKey("author") as! String)\n"
}
增
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
//向指定實(shí)體中插入托管對(duì)象
let object:Book = NSEntityDescription.insertNewObjectForEntityForName("Book", inManagedObjectContext: appDelegate.managedObjectContext) as! Book
object.name = nameText.text
object.author = authorText.text
appDelegate.saveContext()
改
let request = NSFetchRequest(entityName: "Book")
if nameText.text != "" && authorText.text != "" {
let predicate = NSPredicate(format: "%K == %@","name", nameText.text!)
request.predicate = predicate
var result:[NSManagedObject] = []
do{
result = try appDelegate.managedObjectContext.executeFetchRequest(request) as! [NSManagedObject]
} catch {}
if result.count != 0{
resultText.text = ""
for item in result {
//獲取到想要的對(duì)象,改想改的值
item.setValue(authorText.text, forKey: "author")
resultText.text! += "書名:\(item.valueForKey("name") as! String) 作者:\(item.valueForKey("author") as! String)\n"
}
}
}
appDelegate.saveContext()
刪
let request = NSFetchRequest(entityName: "Book")
if nameText.text != "" && authorText.text != "" {
let predicate = NSPredicate(format: "%K == %@","name", nameText.text!)
request.predicate = predicate
var result:[NSManagedObject] = []
do{
result = try appDelegate.managedObjectContext.executeFetchRequest(request) as! [NSManagedObject]
} catch {}
if result.count != 0{
for item in result {
appDelegate.managedObjectContext.deleteObject(item)
}
}
}
appDelegate.saveContext()