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:
下載安裝成功后颁股,點擊打開找到要瀏覽的.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"的選項:
點擊后會生成文件模板:
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é)果:
主要邏輯中用了一段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文件的路徑打印出來了,可以看到:
這里添加了兩條數(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里面添加下文件拷貝:
4. 總結(jié)
Realm作為一款專注于移動平臺的數(shù)據(jù)庫工具捏检,提供了方便不皆、簡介、高效霹娄、快速的操作數(shù)據(jù)的接口,完全可以用來代替SQLite和CoreData犬耻。同時其接口的便利性還帶有一定的Model層性質(zhì),可以減少或者不用其他第三方Model層工具香追。為了用戶方便使用Realm甚至提供了一個Mac上的工具用來查看數(shù)據(jù)庫文件(想想PHPMyAdmin或者MySQLWorkbench的可視化)坦胶,以及一個XCode插件來幫助新建文件內(nèi)容填充,實在是太程序猿友好了顿苇。Realm的具體操作下篇《Realm的CRUD》再述。