嘗鮮Realm

25 May 2016 : 13,949 Commits and 6,148 Closed Issues Later: Thank You for Helping Realm Reach 1.0

從2014年6月宣布“the first mobile-first database.” 開始一也,到2016年5月巢寡,歷經(jīng)2年淬煉的Realm終于發(fā)布了1.0版本,根據(jù)Real?m官方的說法塘秦,這兩年他們和社區(qū)一共做了13讼渊,949次提交、關(guān)閉了6尊剔,148個Issues爪幻,收獲了12,000 個github star,并被上十億(billion)的App用戶啟動,被數(shù)十萬活躍的開發(fā)人員使用须误,而且這其中不乏超級大公司如Twitter挨稿、Alibaba、eBay之流京痢。

所以奶甘,這么漂亮的數(shù)據(jù),你怎么能不去嘗試下呢祭椰?

0. Realm 解決什么問題

在生產(chǎn)環(huán)境的App的制作過程中臭家,持久化數(shù)據(jù)是必不可少的,比如緩存用戶的個人信息方淤、緩存用戶的聯(lián)系人信息等钉赁。而解決方法最常見的就是使用RDB(關(guān)系型數(shù)據(jù)庫)比如SQLite,或者是使用Apple提供的數(shù)據(jù)持久話方案:CoreData⌒現(xiàn)在Realm提供了一個新的解決方案:
沒有SQLite那赤裸的SQL語句
沒有CoreData的復(fù)雜
卻能提供上面二者所能提供的功能你踩,并且速度更快,操作更簡潔讳苦。

Realm是一個專注于移動平臺带膜、提供多種操作接口(Java/Objective-C/Swift/JS-reactivenative/C#-xamarin)的免費的數(shù)據(jù)庫產(chǎn)品。使用Realm就再也不用寫SQL語句了鸳谜,也不用做復(fù)雜的CoreData配置了膝藕。 先來看個官方的例子(OC的例子,其他語言可以在官網(wǎng)找到):

@interface Dog : RLMObject
@property NSString *name;
@property NSInteger age;
@end
@implementation Dog
@end

Dog *dog = [Dog new];
dog.name = @"Rex";
dog.age = 1;

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
    [realm addObject:dog];
}];

RLMResults<Dog *> *allDogs = [Dog allObjects];
RLMResults<Dog *> *pups = [allDogs objectsWhere:@"age < 2"];

這里定義了一個dog對象咐扭,并將其age設(shè)置為1束莫,然后將其存放在被Realm的Dog 實例中,可以認為他就是物理存儲草描,然后用查詢語句"age<2"搜索出所有Dog對象中 age小于2的對象览绿。

1. 安裝Realm

如果目標語言是用的OC的話,那么咱們首選肯定是CocoaPods啦穗慕,在Podfile中添加:

target 'YourApp' do
    pod 'Realm'
end

再執(zhí)行 pod install 等待安裝完成后打開目錄下的.xcworkspace文件就可以了饿敲。

當然也可以直接下載Realm的framework來集成,對于這種提供framework我更傾向于用逛绵,這樣目錄更clean而且第三方插件的版本也很好維護怀各,最新的OC版本framework可在在官網(wǎng)下載realm-objc-1.0.1,然后直接拖到自己的Xcode工程里面就可以了倔韭。

在需要用到的文件中:

#import <Realm/Realm.h>

不報錯就表示設(shè)置成功了,后面就可以使用Realm的接口了瓢对。

如果是用的Swift版本除了Realm.framework還需要RealmSwift.framework 寿酌,也可以用上面的CocoaPods:

target 'YourApp' do
     use_frameworks!
     pod 'RealmSwift'
end

一樣的執(zhí)行 pod install等待安裝完成后打開目錄下的.xcworkspace文件就可以了。

當然同樣的理由硕蛹,我同時也推薦直接使用framework的方式realm-swift-1.0.1醇疼,當然同時也要把Realm.framework拖入到工程中。

在需要用到的文件中:

#import Realm

不報錯就表示可以正常使用Real的Swift接口了法焰。

2. Realm提供的快刀

Realm為了體現(xiàn)他的友好和簡介秧荆,除了提供了SDK以外,還為開發(fā)者提供了一個可以瀏覽數(shù)據(jù)內(nèi)容的App(MacOS)埃仪,想想PHPMyAdmin或者MySQLWorkbench的可視化乙濒,極大的方便了開發(fā)調(diào)試查看÷羊龋可以在AppStore上下載這個Realm Browser:

appstore_realm_browser

下載安裝成功后颁股,點擊打開找到要瀏覽的.realm 的db文件就可以了∩邓浚或者直接雙擊打開.realm文件甘有,會默認用RealmBrowser打開。

除了可以查看數(shù)據(jù)庫文件的工具外桑滩,Realm還為開發(fā)者提供了一個Xcode插件梧疲,其提供了一個創(chuàng)建Realm對象文件的模板(可以根據(jù)當前工程是Objective-C還是Swift自動創(chuàng)建對應(yīng)的文件模板)允睹。方便開發(fā)者修改运准。

插件的安裝可以使用Alcatraz,直接搜索"Realm Plugin"就可以了:

realm_plugin

安裝好之后缭受,當新建文件的時候胁澳,就會有個"realm"的選項:

new_file_with_realm

點擊后會生成文件模板:

realm_file_h

realm_file_m

3. 來個例子

現(xiàn)在來個例子提提神米者,這里創(chuàng)建了一個MacOS下的Objective-C的命令行工具工程,用上面的RealmPlugin插件新建了兩個文件“Studen.h”和"Student.m"蔓搞。然后在main.m中填寫主要邏輯:

@interface Student : RLMObject
@property NSString *name;
@property NSInteger age;  
@end

Realm存儲對象Student包含兩個成員,表示名字的name和年齡的age喂分。

NSString *jsonData = @"[{\\"name\\":\\"wangmeimei\\",\\"age\\":13},{\\"name\\":\\"lilei\\",\\"age\\":14}]";

void demo4realm() {
    NSError *error;
    NSMutableArray *students = [NSJSONSerialization JSONObjectWithData:[jsonData dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];
    if (nil != error) {
        NSLog(@"Parse JSON Error %@", error);
        return ;
    }
    RLMRealm *realmMgr = [RLMRealm defaultRealm];
    NSLog(@"db file is %@",realmMgr.configuration.fileURL);
    for (NSDictionary *s in students) {
        Student *student = [Student new];
        student.age = [[s valueForKey:@"age"] intValue];
        student.name = [s valueForKey:@"name"];
        [realmMgr transactionWithBlock:^{
            [realmMgr addObject:student];
        }];
    }
    
    RLMResults<Student *> *allStudents = [Student allObjects];
    NSLog(@"All students' count %lu", (unsigned long)[allStudents count]);
    RLMResults<Student *> *fs = [allStudents objectsWhere:@"age > 13"];

    for (int i=0; i<[fs count]; i++) {
        Student *s = [fs objectAtIndex:i];
        NSLog(@"Name %@ age is %ld", s.name , (long)s.age);
    }

}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        demo4realm();
    }
    return 0;
}

運行后的結(jié)果:

exe_log

主要邏輯中用了一段JSON數(shù)據(jù) jsonData來表示從網(wǎng)絡(luò)或者從文件中讀取的原始數(shù)據(jù)锦庸。進行反序列化后得到表示學生的數(shù)組數(shù)據(jù)蒲祈。然后依次生成一個個“Student”對象(想象一下如果用SQLite萝嘁,這里可能就需要自己弄一個Model,然后再各種封裝扬卷,是何等的麻煩)牙言。

這里需要一個realm對象 RLMRealm *realmMgr = [RLMRealm defaultRealm]; 獲取預(yù)制的realm管理器,后面的文字我們再介紹怎么去配置它怪得,比如數(shù)據(jù)文件位置等。然后用:

 [realmMgr transactionWithBlock:^{
    [realmMgr addObject:student];
}];

將對象添加數(shù)據(jù)庫中汇恤,先不管這個古怪的語法,先體驗吧因谎。添加完成后,就可以用Realm Browser來看出數(shù)據(jù)了风皿,這里吧默認的db文件.realm文件的路徑打印出來了,可以看到:

realm_browser_db

這里添加了兩條數(shù)據(jù)"wangmeimei"和"lilei"桐款。

后面的代碼邏輯是從數(shù)據(jù)庫中取得所有的Student對象夷恍,然后進行查詢“Age 大于13的?student”魔眨。 這里的[Student allObjects]就可以認為使用SQLite中用SQL命令選中一個Table(當然這個比喻也不是很貼切酿雪,可以自己腦補下)。而RLMResults<Student *> *allStudents就更抽象了指黎,最開始我還以為我OC沒有學好,看不懂這句話的意思杂彭,他大概可以用C++的模板來理解下,一個實際對象是"Student *"的Realm結(jié)果對象指針亲怠。是不是拗口到不行柠辞,反正認為就是“Student *”的容器就可以了,可以用“objectAtIndex:”進行遍歷。

接著一句就是Realm神奇的地方了徙垫,如果用SQLite的話,選取年紀大于13歲的可能要構(gòu)造一個SQL語句

select * from t_student where age>13;

而Realm只需要在上面的結(jié)果中 :

[allStudents objectsWhere:@"age > 13"]

就搞定了己英,目標是allStudents,條件是“age>13”损肛,表達性更強荣瑟。結(jié)果依舊是抽象的"RLMResults<Student *> *"用“objectAtIndex:”進行遍歷下就可以了治拿。

如果是Swift的話笆焰,代碼如下:

import Foundation
import RealmSwift

let jsonData  = "[{\\"name\\":\\"wangmeimei\\",\\"age\\":13},{\\"name\\":\\"lilei\\",\\"age\\":14}]"

func demo4realm() {
    print(jsonData)
    var error: NSError?
    let students : NSArray = try! NSJSONSerialization.JSONObjectWithData(jsonData.dataUsingEncoding(NSUTF8StringEncoding)!,
                                                                         options: NSJSONReadingOptions.MutableContainers) as! NSArray
    let realmMgr = try! Realm()
    print("default db is ", realmMgr.configuration.fileURL)
    
    for s in students {
        let student = Student()
        student.name  = s.objectForKey("name") as! String
        student.age = s.objectForKey("age") as! Int
        
        try! realmMgr.write {
            realmMgr.add(student)
        }
    }
    
    let pups = realmMgr.objects(Student.self).filter("age > 13")
    for (var i=0; i<pups.count ; i++) {
        let s = pups[i];
        print("Name %@ age is %ld", s.name, s.age);
    }
    
}

demo4realm()

在使用Swift的時候,在MacOS上可能會報dyld找不到Real.framework:

dyld: Library not loaded: @rpath/Realm.framework/Versions/A/Realm
Referenced from: /Users/HTAD/Library/Developer/Xcode/DerivedData/REALM-cdxzyeduoxphmoefhjxihxunuzkd/Build/Products/Debug/REALM.app/Contents/MacOS/REALM
Reason: image not found
(lldb)

需要在Build Phases里面添加下文件拷貝:

realm_framework

4. 總結(jié)

Realm作為一款專注于移動平臺的數(shù)據(jù)庫工具捏检,提供了方便不皆、簡介、高效霹娄、快速的操作數(shù)據(jù)的接口,完全可以用來代替SQLite和CoreData犬耻。同時其接口的便利性還帶有一定的Model層性質(zhì),可以減少或者不用其他第三方Model層工具香追。為了用戶方便使用Realm甚至提供了一個Mac上的工具用來查看數(shù)據(jù)庫文件(想想PHPMyAdmin或者MySQLWorkbench的可視化)坦胶,以及一個XCode插件來幫助新建文件內(nèi)容填充,實在是太程序猿友好了顿苇。Realm的具體操作下篇《Realm的CRUD》再述。

參考

  1. Realm
  2. Realm Objective-C
  3. Realm Swift
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凑队,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子漩氨,更是在濱河造成了極大的恐慌,老刑警劉巖叫惊,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異霍狰,居然都是意外死亡,警方通過查閱死者的電腦和手機蔗坯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門宾濒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腿短,“玉大人绘梦,你說我怎么就攤上這事⊙枰В” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵择卦,是天一觀的道長。 經(jīng)常有香客問我祈噪,道長,這世上最難降的妖魔是什么辑鲤? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任杠茬,我火速辦了婚禮,結(jié)果婚禮上瓢喉,老公的妹妹穿的比我還像新娘。我一直安慰自己栓票,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惑芭,像睡著了一般继找。 火紅的嫁衣襯著肌膚如雪强衡。 梳的紋絲不亂的頭發(fā)上码荔,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天缩搅,我揣著相機與錄音,去河邊找鬼硼瓣。 笑死,一個胖子當著我的面吹牛堂鲤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘟栖,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酬滤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盯串,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戒良,失蹤者是張志新(化名)和其女友劉穎体捏,沒想到半個月后糯崎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡奏司,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年樟插,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黄锤。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鸵熟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情流强,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布队腐,位于F島的核電站,受9級特大地震影響柴淘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜为严,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一肺稀、第九天 我趴在偏房一處隱蔽的房頂上張望第股。 院中可真熱鬧话原,春花似錦、人聲如沸稿静。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悬钳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碉渡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工滞诺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人习霹。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像淋叶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子煞檩,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

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