Realm,為移動(dòng)設(shè)備而生忍啤。替代 SQLite 和 Core Data。
官方中文文檔:官方文檔
以上是官方文檔胎食,大家看過后有個(gè)大體了解扰才。
說一下我對Realm的認(rèn)識(shí)。
首先它的API調(diào)用特別舒服厕怜,不繁瑣衩匣。
還有一個(gè)好處就是省心蕾总,不用像CoreData那樣復(fù)雜的管理。也不用寫SQL語句琅捏∩伲總之,簡單柄延!
高效蚀浆,開發(fā)中應(yīng)用測試時(shí),無論是那種操作搜吧,都是秒操作市俊。所以性能不是問題。
下面是具體操作(看過官方文檔滤奈,有一定認(rèn)識(shí)后在操作)
我只是復(fù)述一下我對官方文檔的理解摆昧,以及我集成Realm的過程操作
從這里開始(集成過程)
Realm是開源的~,下載方式靜態(tài)庫蜒程,以及官方Demo绅你。下載 Realm OC版(Swift版和OC版是不能共存的):下載OC版Realm
準(zhǔn)備工作
使用 Realm 構(gòu)建應(yīng)用的基本要求:iOS >= 7, OS X >= 10.9 并且支持 WatchKit。昭躺;
需要使用 Xcode 6.4 或者以后的版本忌锯;
程序支持Objective?C, Swift 1.2 & Swift 2.x。
安裝 (這里有好多可選的方式窍仰,看大家喜歡汉规,我用的是靜態(tài)庫)
1.動(dòng)態(tài)框架
2.CocoaPod
3.Carthage
4.靜態(tài)框架(因?yàn)槠渌男枰┠_本)
Realm瀏覽器/數(shù)據(jù)庫管理器
官方提供了一個(gè)名為Realm Browser的Mac應(yīng)用,用來進(jìn)行Realm數(shù)據(jù)的讀取和編輯驹吮。(好用针史,但是每次編譯寫入新數(shù)據(jù)的時(shí)候,之前打開的會(huì)閃退)
Xcode 插件
怎么安裝就不贅述了碟狞,最開始的時(shí)候我會(huì)用啄枕,后來用多了,就自己手動(dòng)建模型類了族沃。
API手冊
能查詢Realm的完整版API手冊频祝,里面包含了所有類和方法等信息。
示例
官方Demo里有(好多脆淹,而且是英文不是很懂)
數(shù)據(jù)模型(Model)
Realm數(shù)據(jù)模型是基于標(biāo)準(zhǔn) Objective?C 類來進(jìn)行定義的常空,使用屬性來完成模型的具體定義。
通過簡單的繼承RLMObject或者一個(gè)已經(jīng)存在的模型類盖溺,您就可以創(chuàng)建一個(gè)新的 Realm 數(shù)據(jù)模型對象漓糙。
Realm模型對象在形式上基本上與其他 Objective?C 對象相同 - 您可以給它們添加您自己的方法(method)和協(xié)議(protocol),和在其他對象中使用類似烘嘱。
主要的限制是某個(gè)對象只能在其被創(chuàng)建的那個(gè)線程中使用, 并且您無法訪問任何存儲(chǔ)屬性的實(shí)例變量(ivar)昆禽。
如果您安裝了我們的Xcode插件蝗蛙,那么可在”New File…“對話框中會(huì)有一個(gè)很漂亮的模板,可用來創(chuàng)建接口(interface)和執(zhí)行(implementation)文件醉鳖。
您只需要為對象的類型列表添加目標(biāo)類型的屬性捡硅,或者RLMArray,就可以創(chuàng)建數(shù)據(jù)關(guān)系(relationship)和嵌套數(shù)據(jù)結(jié)構(gòu)(nested data structure)盗棵。
我就不用官方文檔里的類說明了壮韭,以下就是實(shí)際項(xiàng)目(gitDemo)中類的創(chuàng)建以及使用
導(dǎo)入項(xiàng)目中的DataStore文件夾
拖進(jìn)來之后(確保拖入時(shí)勾選了 Copy items if needed ),可能會(huì)報(bào)錯(cuò)漾根,查看報(bào)錯(cuò)信息泰涂,(一般是缺少libc++.tbd)
建模型的基類
我將常用的數(shù)據(jù)庫操作已經(jīng)做了封裝,在Store文件夾下是Realm數(shù)據(jù)庫的管理類辐怕,同時(shí)每個(gè)模型類都需要主鍵逼蒙,所以應(yīng)該抽象出父類來持有primaryKey和realmManager是有必要的。
模型類需要跟官方文檔里描述一致需要繼承RLMObject類RLM_ARRAY_TYPE(BasicRealm)定義一個(gè)RLMArray類型(不太明白的可以看一下官方源碼)
#import <Realm/Realm.h>
#import"RLMObject+JSON.h"
#import"XMRealmStoreManager.h"
@interfaceBasicRealm :RLMObject
/**
*本地?cái)?shù)據(jù)庫入庫的主鍵ID
*/
@property(nonatomic,copy)NSString*hostID;
/**
* realm數(shù)據(jù)管理
*
* @return realm數(shù)據(jù)管理
*/
+(XMRealmStoreManager*)realmManager;
-(XMRealmStoreManager*)realmManager;
@end
// This protocol enables typed collections. i.e.:
// RLMArray
RLM_ARRAY_TYPE(BasicRealm)
@interfaceBasicModel :NSObject
@property(nonatomic,copy)NSString*hostID;
@end
.m文件的具體方法請從項(xiàng)目中查看
建數(shù)據(jù)模型類
現(xiàn)在就可以根據(jù)項(xiàng)目需求建立明確的模型類寄疏,模型類需要繼承上述的基類BasicRealm是牢。
假如現(xiàn)在的需求是Cell的標(biāo)題下有三張圖片(大家自行腦補(bǔ)一下UI),那么我們需要標(biāo)題屬性陕截,以及一個(gè)圖片鏈接數(shù)組(Realm中不能用NSArray驳棱,需要用RLMArray)屬性聲明如下
#import"BasicModel.h"
RLM_ARRAY_TYPE(ImageRealm)//定義一個(gè)RLMArray類型
@interfaceDataRealm :BasicRealm
@property(nonatomic,copy)NSString*title;
@property(nonatomic,strong)RLMArray * image_url;
@end
@interfaceImageRealm :BasicRealm
@property(nonatomic,copy)NSString*image;
@end
.m中需要重寫兩個(gè)方法
+ (NSDictionary*)JSONInboundMappingDictionary
(入庫的keyPath對應(yīng)模型的keyPath)
+ (NSDictionary*)JSONOutboundMappingDictionary
(出庫的keyPath對應(yīng)模型的keyPath)
兩個(gè)方法一般內(nèi)容都相同,一般我們寫的模型類都是基于服務(wù)器返回?cái)?shù)據(jù)的KeyPath作為我們數(shù)據(jù)類的屬性名农曲。但當(dāng)服務(wù)器返回的數(shù)據(jù)(比如服務(wù)器數(shù)據(jù)庫的主鍵是id社搅,當(dāng)然你也可以跟服務(wù)端開發(fā)商量一下提前做一下key的更改,畢竟好兄弟~)有一些OC的關(guān)鍵詞比如id這樣的話我們就需要將入(出)庫的keyPath對應(yīng)模型的keyPath做一下映射的更改
@implementationDataRealm
+ (NSDictionary*)JSONInboundMappingDictionary {
return@{
@"hostID":@"hostID",
@"image_url":@"image_url",
@"title":@"title",
};
}
+ (NSDictionary*)JSONOutboundMappingDictionary {
return@{
@"hostID":@"hostID",
@"image_url":@"image_url",
@"title":@"title",
};
}
@end
@implementationImageRealm
+ (NSDictionary*)JSONInboundMappingDictionary {
return@{
@"hostID":@"hostID",
@"image":@"image",
};
}
+ (NSDictionary*)JSONOutboundMappingDictionary {
return@{
@"hostID":@"hostID",
@"image":@"image",
};
}
@end
Realm數(shù)據(jù)模型類的使用
用Realm管理類調(diào)用數(shù)據(jù)的增刪改差
//增or改
-(void)add
{
[[DataRealmrealmManager]writeObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//在這返回一個(gè)id對象可以是一個(gè)包含多個(gè)數(shù)據(jù)庫模型的數(shù)組乳规,也可以是單個(gè)數(shù)據(jù)庫模型對象可以調(diào)用Real自己的解析字典方法形葬,也可以用封裝好的方法(根據(jù)服務(wù)器返回的數(shù)據(jù)類型)
return[DataRealmcreateOrUpdateInRealm:realmwithJSONDictionary:@{@"hostID":@"1",@"title":@"好好學(xué)習(xí)天天向上",@"image_url":@[@{@"hostID":@"1",@"image":@"http://image1"},@{@"hostID":@"2",@"image":@"http://image2"},@{@"hostID":@"3",@"image":@"http://image3"}]}];
// return [DataRealm createOrUpdateInRealm:realm withJSONArray:@[]];
}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm) {
//事務(wù)完成后回調(diào)
}];
}
//刪
-(void)delete{
[[DataRealmrealmManager]deleteObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//可以根據(jù)sql語句查找刪除
return[DataRealmobjectsWhere:@""];
//也可以根據(jù)主鍵獲得
return[DataRealmobjectForPrimaryKey:@"1"];
}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm) {
//事務(wù)完成回調(diào)
}];
}
//查
-(void)search
{
[[DataRealmrealmManager]fetchObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//可以根據(jù)sql語句查找刪除
return[DataRealmobjectsWhere:@""];
//也可以根據(jù)主鍵獲得
return[DataRealmobjectForPrimaryKey:@"1"];
}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm,RLMResults*results,NSString*primaryKey,NSMutableArray*models) {
//事務(wù)完成回調(diào)獲得查詢內(nèi)容更新UI
}];
}
后語:
我建議大家將數(shù)據(jù)分為兩種類,一種是數(shù)據(jù)庫類暮的,一種是平常我們不做數(shù)據(jù)存儲(chǔ)的類(我在Demo (由于git文件大小限制不能上傳Realm.framework笙以,請大家自行拖入)中是這樣操作的)。這樣做的好處是分開來易于管理冻辩,那些屬性內(nèi)容需要入庫就在數(shù)據(jù)庫類中聲明猖腕,不需要的但是我們UI展示上需要的在單獨(dú)的數(shù)據(jù)類中。這樣數(shù)據(jù)庫中就不需要冗余的key(當(dāng)然也可以通過.m的兩種方法來控制入庫的keyPath)這樣做還有一個(gè)不算原因的原因恨闪,這樣做可以用一些字典轉(zhuǎn)模型的解析類框架(比如MJ倘感,YYModel等)×剩總是這項(xiàng)看個(gè)人喜好吧侠仇。