- 參考書籍:CORE DATA by Tutorials
- 默認(rèn)有swift基礎(chǔ)音羞。
最近一直在學(xué)習(xí)CoreData相關(guān)內(nèi)容,在這里做一個(gè)總結(jié),總結(jié)分篇組成津坑,以供自己和他人學(xué)習(xí)參考。
Core Data 是一個(gè)在OS X和iOS SDKs中對(duì)象圖形化管理以及持久化的框架傲霸。這意味著Core Data可以用來(lái)存儲(chǔ)以及獲取數(shù)據(jù)疆瑰,但這并不是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)如同MySQL和SQLite。但是事實(shí)上Core Data使用的是SQLite來(lái)存儲(chǔ)數(shù)據(jù)的昙啄。我的理解是Core Data是蘋果對(duì)SQLite的進(jìn)一步升級(jí)穆役,使你可以不用關(guān)注數(shù)據(jù)的存儲(chǔ)而把重心放在對(duì)象的增刪改查。
這一篇主要內(nèi)容:
1梳凛、使用Xcode建立CoreData模型耿币。
2、添加數(shù)據(jù)韧拒。
3淹接、讀取數(shù)據(jù)。
(1)叛溢、建立模型
建立一個(gè)新工程塑悼,如下圖所示。
Note:在xcode6中只有Master-Detail Application 和Single View Application這兩個(gè)模板有這個(gè)勾選框楷掉。
你會(huì)發(fā)現(xiàn)AppDelegate.swift文件中多出了一些代碼政勃,以及多了一個(gè)CoreDataTest1.xcdatamodeld文件懂诗。
AppDelegate.swift中多出的代碼暫且不用管他,在后面我們會(huì)用到。
點(diǎn)擊*.xcdatamodeld文件胖烛,點(diǎn)擊Add Entity按鈕添加Entity济舆,將其重新命名為Test涩嚣,在右邊的Attributes欄點(diǎn)擊加號(hào)赃梧,添加一個(gè)Attribute,并將type選擇為Sring墩虹。
- Note:Entity的名字必須以大寫開頭
這樣你就添加了一個(gè)Entity實(shí)體嘱巾,叫做Test,這個(gè)實(shí)體有一個(gè)屬性名為name败晴,為String類型浓冒。在這里解釋一下這幾個(gè)名詞的意義:
- Entity:相當(dāng)于coredata中的類。
- Attribute:如果entity是類的話尖坤,attribute就是類的屬性稳懒,各自為不同類型。
(還有一些其他屬性在后面的章節(jié)會(huì)介紹。)
通過(guò)以上操作我們就成功的創(chuàng)建了一個(gè)CoreData的Model场梆。
(2)墅冷、保存數(shù)據(jù)
為了方便演示,我們?nèi)∠鸄utoLayout或油,并拖入幾個(gè)UI控件寞忿,制作一個(gè)簡(jiǎn)單的Demo。
好的腔彰,接下來(lái)就是添加數(shù)據(jù)的相關(guān)操作。
首先辖佣,打開viewcontroller.swift霹抛,添加頭文件“import CoreData”。
然后卷谈,在addButton方法內(nèi)添加以下代碼:
<pre><code>
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("Test", inManagedObjectContext:
managedContext)
let test = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
//3
let name = self.addTextField.text
test.setValue(name, forKey: "name")
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save (error), (error?.userInfo)")
}
</code></pre>
讓我來(lái)解釋一下這一段代碼:
//1 在我們想要保存或者獲取任何數(shù)據(jù)之前我們必須獲取NSManagedObjectContext杯拐,你可以把這個(gè)東西理解為暫存器。
(這個(gè)對(duì)象就是我們前面提到的AppDelegate中自動(dòng)生成的代碼之一世蔗,如果你在創(chuàng)建工程的時(shí)候勾選了‘Use Core Data’)
我們通過(guò) Application.delegate 獲取了xcode自動(dòng)生成的‘暫存器’端逼。-
//2 好的,經(jīng)過(guò)上一步我們擁有了一個(gè)暫存器污淋,現(xiàn)在我們想保存對(duì)象的首先得創(chuàng)造這個(gè)對(duì)象顶滩,這個(gè)對(duì)象是NSManagedObject類型的,通過(guò)初始化方法:
init(entity:insertIntoManagedObjectContext:)
這個(gè)方法給我們的entity也就是實(shí)體創(chuàng)建了一個(gè)能加入到‘暫存器’中的對(duì)象芙沥。NSEntityDescription.entityForName(entityName: String, inManagedObjectContext context: NSManagedObjectContext)
這個(gè)方法按照名字尋找到我們?cè)O(shè)定的entity诲祸,并且和我們的‘暫存器’連接起來(lái)浊吏。
- //3 上一步我生成了一個(gè)NSManagedObject對(duì)象而昨,這個(gè)對(duì)象有一個(gè)屬性“name”,這一步做的就是給這個(gè)屬性賦值找田。
test.setValue(name, forKey: "name")
key-value大家應(yīng)該不會(huì)陌生歌憨。這樣,我們新創(chuàng)建的對(duì)象的屬性就有了值墩衙,這個(gè)值就是我們輸入到輸入框的值务嫡。
到這一步,我們的entity有了值漆改,并且我們的entity已經(jīng)進(jìn)入添加到了‘暫存器’中心铃。 - //4 我們前面一直在說(shuō)存到‘暫存器’中,既然是‘暫存器’挫剑,那么最后一步就是把‘暫存器’中的東西存到磁盤中去扣。保存的方法很簡(jiǎn)單:
managedContext.save(&error)
error是存盤發(fā)生錯(cuò)誤時(shí)產(chǎn)生錯(cuò)誤原因,一個(gè)好的app必須對(duì)各種error進(jìn)行處理樊破。
通過(guò)以上四步我們就成功將輸入到TextField中的字符串存到了磁盤中
(3)愉棱、讀取數(shù)據(jù)
這一部分我們的目標(biāo)是將前面存入磁盤的內(nèi)容再?gòu)拇疟P中讀出來(lái)唆铐,并在TextView中顯示。
在showButton方法中添加以下代碼:
<pre><code>
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let fetchRequest = NSFetchRequest(entityName:"Test")
//3
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
if let results = fetchedResults {
for each in results{
let name:String = each.valueForKey("name") as! String
self.showTextView.text = self.showTextView.text + name + "\n"
}
}else {
println("Could not fetch (error), (error!.userInfo)")
}
</code></pre>
- //1 前面已經(jīng)說(shuō)過(guò)奔滑,不管是儲(chǔ)存還是讀取數(shù)據(jù)艾岂,首先得獲取managedObjectContext對(duì)象,獲取方法與之前相同朋其,通過(guò)Application delegate的方式獲取王浴。
- //2 想要讀取數(shù)據(jù),第二步就是告訴系統(tǒng)想要的讀取數(shù)據(jù)的entity
let fetchRequest = NSFetchRequest(entityName:"Test")
NSFetchRequest這是對(duì)‘寄存器發(fā)出請(qǐng)求梅猿,告訴‘寄存器’’我們要獲取數(shù)據(jù)的實(shí)體叼耙。 - //3 通過(guò)前兩步,我們已經(jīng)有了‘寄存器’粒没,以及想要獲取數(shù)據(jù)的實(shí)體的請(qǐng)求筛婉。那么這一步對(duì)‘寄存器’發(fā)出請(qǐng)求,就可以返回一個(gè)數(shù)組癞松,這個(gè)數(shù)組包括了所有符合要求的實(shí)體爽撒,每一個(gè)實(shí)體都是我么之前存進(jìn)去的對(duì)象。
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
fetchedResults就是這個(gè)包含所有‘Test’對(duì)象的數(shù)組响蓉,我們用一個(gè)for in 函數(shù)將數(shù)組中的每一個(gè)對(duì)象都讀出來(lái)
let name:String = each.valueForKey("name") as! String
.valueForkey(String)函數(shù)可以將對(duì)象中的屬性的值讀出來(lái)
- Nete:如果‘寄存器’中沒(méi)有這個(gè)實(shí)體的數(shù)據(jù)硕勿,也就是數(shù)組中沒(méi)有對(duì)象,那么我們獲取的fetchedResults數(shù)組是這樣的“[]”.
但是如果請(qǐng)求發(fā)生了錯(cuò)誤枫甲,那么該方法返回的是一個(gè)nil源武,所以我們可以通過(guò)if let 來(lái)判斷是否發(fā)生了錯(cuò)誤,如果發(fā)生了錯(cuò)誤我們可以輸出error.userInfo來(lái)進(jìn)行一個(gè)提示想幻。
好的粱栖,我們通過(guò)以上操作就將數(shù)據(jù)讀取出來(lái)并顯示在了TextView中,我們來(lái)操作一下app脏毯,結(jié)果如下所示:
在以上內(nèi)容中我們學(xué)習(xí)了這些知識(shí)點(diǎn):
- data models
- entities
- attributes
- managed objects
- managed object contexts
- fetch requests.
再來(lái)總結(jié)一下:
- 儲(chǔ)存數(shù)據(jù):
1食店、獲取‘暫存器’——NSManagedObjectContext渣淤。
2、聲明想要儲(chǔ)存的實(shí)體對(duì)象NSManagedObject吉嫩。
用test.setValue(name, forKey: "name")方法給聲明的實(shí)體對(duì)象的屬性賦值
3价认、保存- 讀取數(shù)據(jù)
1、獲取‘暫存器’——NSManagedObjectContext自娩。
2用踩、創(chuàng)建請(qǐng)求NSFetchRequest
3、
managedContext.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
方法返回?cái)?shù)據(jù),該數(shù)據(jù)是一個(gè)包括所有符合要求的實(shí)體對(duì)象的數(shù)組捶箱。
如果發(fā)生錯(cuò)誤智什,方法返回nil。
這一篇中我們進(jìn)行了簡(jiǎn)單的存貯以及讀取操作丁屎,下一篇中我們會(huì)對(duì)CoreData進(jìn)行更多的操作荠锭。
源代碼已上傳github:https://github.com/superxlx/CoreDataTest1