移動(dòng)開發(fā)數(shù)據(jù)庫(kù)篇 之 SwiftRealm(上)

移動(dòng)開發(fā)數(shù)據(jù)庫(kù)篇 之 SwiftRealm(上)


@author fharmony Email Weibo or Github


Realm is a mobile database
hundreds of millions of people rely on .

1. 為什么要使用SwiftRealm?

新型數(shù)據(jù)庫(kù)白粉,同類型三方庫(kù)有CoreDataSQLite
特點(diǎn):簡(jiǎn)單怒竿、快铅祸、文檔規(guī)范咐容、免費(fèi)
需要:iOS 8.0+(指的是Swift版本)

需要繼承Object毫缆,具有一定程度的侵入性重绷。和AVOS Object類似银酗。但是需要注意的是慎框,如果使用的話realm是存儲(chǔ)在本地的數(shù)據(jù)良狈,和AVOS Object存儲(chǔ)在云端的數(shù)據(jù)作用不一樣。

快速集成

使用Cocoapods快速集成笨枯,請(qǐng)參考這個(gè)文章
podfile內(nèi)容:

platform :ios,'8.0'
use_frameworks!
target '<#你的TargetName#>' do
pod 'RealmSwift'
end

2. 數(shù)據(jù)模型 - 關(guān)系

數(shù)據(jù)模型的創(chuàng)建

可以使用Realm提供的Realm Model創(chuàng)建薪丁,文件需要滿足:

  • 指定數(shù)據(jù)類型或者是List類型
  • 一定需要初始化

數(shù)據(jù)模型的關(guān)系

  • 一對(duì)一關(guān)系 可以為空
  • 一對(duì)多關(guān)系 通過(guò)List完成,提供了List類來(lái)作為列表
  • 反向關(guān)系 可以通過(guò)一個(gè)特定的屬性獲取和給定對(duì)象有關(guān)系的所有對(duì)象馅精。即「具有XX屬性的那些對(duì)象」

數(shù)據(jù)類型:

常用類型:Bool\Double\Float\String\NSDate\NSData\Int32\Object
可選與不可選類型

* 對(duì)于基本類型來(lái)說(shuō):
let style = RealmOptional<Int32>() --> 可選值
dynamic var style = 32 --> 不可選值

* 對(duì)對(duì)象類型來(lái)說(shuō)
let var value:Stirng? = nil --> 可選值
dynamic var value = ""

為什么使用dynamic严嗜?因?yàn)閞ealm工作基于OC運(yùn)行時(shí)。
為什么不使用計(jì)算屬性洲敢?計(jì)算屬性將不會(huì)被存儲(chǔ)到realm里面

索引屬性

重寫Object.indexedProperties()添加索引屬性漫玄,支持用字符串、整數(shù)沦疾、布爾值称近、NSDate作為索引,有利于提高檢索效率哮塞。

主鍵

重寫Object.primaryKey()添加主鍵刨秆,主鍵不可修改而且能讓查詢更加高效。注意數(shù)據(jù)庫(kù)的主鍵是條目的唯一標(biāo)示忆畅,如果有兩條主鍵相同的條目衡未,那么后來(lái)的條目會(huì)更新前一個(gè)條目的數(shù)據(jù)。

忽略屬性

重寫 Object.ignoredProperties() 可以忽略 Realm 存儲(chǔ)數(shù)據(jù)模型的某個(gè)屬性家凯。

3.對(duì)數(shù)據(jù)庫(kù)的操作

對(duì)象存儲(chǔ)

對(duì)對(duì)象存儲(chǔ)的更改需要通過(guò)寫入事務(wù)write閉包完成缓醋。
如果您想要在多個(gè)線程中共享對(duì)象,或者在應(yīng)用重啟后重復(fù)使用對(duì)象绊诲,那么您必須將其存儲(chǔ)到Realm數(shù)據(jù)庫(kù)中——這個(gè)操作必須在寫入事務(wù)中完成送粱。
寫入事務(wù)可能會(huì)失敗,所以需要添加throws標(biāo)記處理異常

  • 增刪改
let realm = try! Realm()//建立realm數(shù)據(jù)庫(kù)
try! realm.write{
    realm.add(object)//插入新對(duì)象
    object.name = "new value"http://更新數(shù)值
    realm.add(object,update:true)//對(duì)已經(jīng)存在的值進(jìn)行更新操作掂之,或者是對(duì)不存在的值進(jìn)行寫入抗俄,是否存在依據(jù)的是主鍵
    realm.delete(object)//刪除對(duì)象

}

* 查  

返回Results實(shí)例,查詢得到的是數(shù)據(jù)庫(kù)里面的數(shù)據(jù)世舰,在寫入操作的時(shí)候可以修改數(shù)據(jù)庫(kù)的數(shù)據(jù)动雹。您可以將 Results 存儲(chǔ)為一個(gè)屬性,這樣就無(wú)需在每次訪問(wèn)前都要刷新數(shù)據(jù)以確保數(shù)據(jù)最新了跟压。realm的查詢?cè)试S鏈?zhǔn)讲樵儭?/p>

let dogs = realm.Objects(Dog)
let tanDogs = realm.Objects(Dog).filter("NSPredicate斷言")
  • 排序
    根據(jù)某個(gè)屬性進(jìn)行排序
let sortedDogs = realm.objects(Dog).filter("color = '棕黃色' AND name BEGINSWITH 'B'").sorted("color")

創(chuàng)建對(duì)象

var myDog = Dog()
和swift新建對(duì)象的方法一致

創(chuàng)建數(shù)據(jù)庫(kù)

通過(guò)調(diào)用 Realm()會(huì)在應(yīng)用文件夾下的一個(gè)名為“default.realm”的文件胰蝠,realm.path來(lái)獲取realm數(shù)據(jù)庫(kù)地址,可以使用Realm Browser進(jìn)行查看

配置realm

通過(guò)Realm.Configuration您可以配置諸如 Realm 文件在何處存儲(chǔ)之類的信息。蘋果推薦<Application_Home>/Library/Caches目錄下茸塞,
在生成 Realm 文件的代碼處躲庄,您需要結(jié)尾對(duì)文件進(jìn)行壓縮拷貝(參見 Realm().writeCopyToPath(_:encryptionKey:))。 這有助于減少 Realm 的文件體積翔横,讓您發(fā)布的應(yīng)用體積更卸刘巍;

刪除數(shù)據(jù)庫(kù)

大多數(shù)文件可以通過(guò)removeItemAtPath刪除禾唁,但是您必須要采取額外的操作效览,來(lái)確保沒(méi)有任何活躍的 Realm 對(duì)象在刪除過(guò)程中訪問(wèn)數(shù)據(jù)庫(kù)。Realm 實(shí)例將會(huì)在它們的整個(gè)生命周期中荡短,持有對(duì)數(shù)據(jù)庫(kù)的連接丐枉。限制 Realm 實(shí)例生命周期的方法就是使用 autorelease pool 將其使用操作包含在其中。所有 path 指向您想要?jiǎng)h除的 Realm 文件的 Realm 實(shí)例掘托,都必須要在刪除操作執(zhí)行前被釋放掉瘦锹。

4. 多線程

Realm 通過(guò)確保每個(gè)線程始終擁有 Realm 的一個(gè)快照,以便讓并發(fā)運(yùn)行變得十分輕松闪盔。您唯一需要注意的一件事情就是不能讓多個(gè)線程都持有同一個(gè) Realm 對(duì)象的 實(shí)例 弯院。如果定期刷新 Realm 失敗的話,就可能會(huì)導(dǎo)致某些事務(wù)的版本變?yōu)椤版i定(pinned)”狀態(tài)泪掀,阻止 Realm 重用該版本的硬盤空間听绳,從而導(dǎo)致文件尺寸變大。
不支持 跨線程共享Realm 實(shí)例异赫。 Realm 實(shí)例要訪問(wèn)相同的 Realm 文件還必須使用相同的 Realm.Configuration椅挣。
當(dāng)你同時(shí)進(jìn)行多個(gè)寫操作的時(shí)候,他們會(huì)相互阻塞塔拳,阻塞住他們所運(yùn)行的線程鼠证。因此您必須要為每一個(gè)您想要執(zhí)行讀取或者寫入操作的線程或者dispatch隊(duì)列創(chuàng)建一個(gè) Realm 實(shí)例。所以應(yīng)當(dāng)考慮在 UI 之外的線程中來(lái)進(jìn)行操作靠抑。另外需要注意的是量九,在進(jìn)行寫事務(wù)的時(shí)候,讀操作并不會(huì)造成阻塞颂碧。這非常有用荠列,尤其是當(dāng)你在后臺(tái)進(jìn)行寫操作的時(shí)候,用戶可能會(huì)在不同界面切換稚伍,而這時(shí)候可以進(jìn)行讀操作
Realm 對(duì)象在每個(gè)線程中都應(yīng)該只被創(chuàng)建一次弯予,因?yàn)樗皇蔷€程安全的戚宦,不能在不同的線程中共享个曙。如果你想要在另一個(gè)線程中執(zhí)行寫操作,那么就需要?jiǎng)?chuàng)建一個(gè)新的 Realm 對(duì)象。
建議你使用常用的垦搬,也是最有效的方案呼寸, 將所有寫入放到一個(gè)單獨(dú)的進(jìn)程中。

5. 其他

通知

通過(guò)調(diào)用 addNotificationBlock 方法進(jìn)行通知注冊(cè)后猴贰,無(wú)論哪個(gè) Realm, Results 或者 List 對(duì)象更新对雪,都可以得到通知。Results 以及 List 實(shí)例在注冊(cè)的時(shí)候米绕,會(huì)使用初始的集合來(lái)調(diào)用閉包瑟捣,然后當(dāng)每次寫事務(wù)對(duì)集合或者包含在其中的任何事物進(jìn)行改變之后,會(huì)再次調(diào)用一遍此閉包栅干。

加密

  • 在iOS平臺(tái)中迈套,通過(guò)使用 NSFileProtection API 就可以花費(fèi)極小的代價(jià)完成 Realm 的文件加密。
  • 使用realm官方的加密方法:
// 產(chǎn)生隨機(jī)密鑰
let key = NSMutableData(length: 64)!
SecRandomCopyBytes(kSecRandomDefault, key.length,
    UnsafeMutablePointer<UInt8>(key.mutableBytes))

// 打開加密文件
let config = Realm.Configuration(encryptionKey: key)
do {
  let realm = try Realm(configuration: config)
  // 和往常一樣使用 Realm 即可
  let dogs = realm.objects(Dog).filter("name contains 'Fido'")
} catch let error as NSError {
  // 如果密鑰錯(cuò)誤碱鳞,`error` 會(huì)提示數(shù)據(jù)庫(kù)不可訪問(wèn)
  fatalError("Error opening realm: \(error)")
}

參考資料

Realm Swift官方文檔


                                —— 念念不忘桑李,必有回響

@author fharmony Email Weibo or Github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窿给,隨后出現(xiàn)的幾起案子贵白,更是在濱河造成了極大的恐慌,老刑警劉巖崩泡,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禁荒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡允华,警方通過(guò)查閱死者的電腦和手機(jī)圈浇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)靴寂,“玉大人磷蜀,你說(shuō)我怎么就攤上這事“倬妫” “怎么了褐隆?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剖踊。 經(jīng)常有香客問(wèn)我庶弃,道長(zhǎng),這世上最難降的妖魔是什么德澈? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任歇攻,我火速辦了婚禮,結(jié)果婚禮上梆造,老公的妹妹穿的比我還像新娘缴守。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布屡穗。 她就那樣靜靜地躺著贴捡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪村砂。 梳的紋絲不亂的頭發(fā)上烂斋,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音础废,去河邊找鬼汛骂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛评腺,可吹牛的內(nèi)容都是我干的香缺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼歇僧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼图张!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诈悍,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤祸轮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后侥钳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體适袜,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年舷夺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苦酱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡给猾,死狀恐怖疫萤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敢伸,我是刑警寧澤扯饶,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站池颈,受9級(jí)特大地震影響尾序,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躯砰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一每币、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琢歇,春花似錦兰怠、人聲如沸则北。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至涌矢,卻和暖如春掖举,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娜庇。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工塔次, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人名秀。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓励负,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匕得。 傳聞我的和親對(duì)象是個(gè)殘疾皇子继榆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容