Realm,為移動設備而生。替代 SQLite 和 Core Data。
官方中文文檔:官方文檔
以上是官方文檔,大家看過后有個大體了解。
說一下我對Realm的認識。
首先它的API調用特別舒服,不繁瑣。
還有一個好處就是省心,不用像CoreData那樣復雜的管理。也不用寫SQL語句。總之,簡單!
高效,開發中應用測試時,無論是那種操作,都是秒操作。所以性能不是問題。
下面是具體操作(看過官方文檔,有一定認識后在操作)
我只是復述一下我對官方文檔的理解,以及我集成Realm的過程操作
從這里開始(集成過程)
Realm是開源的~,下載方式靜態庫,以及官方Demo。下載 Realm OC版(Swift版和OC版是不能共存的):下載OC版Realm
準備工作
使用 Realm 構建應用的基本要求:iOS >= 7, OS X >= 10.9 并且支持 WatchKit。;
需要使用 Xcode 6.4 或者以后的版本;
程序支持Objective?C, Swift 1.2 & Swift 2.x。
安裝 (這里有好多可選的方式,看大家喜歡,我用的是靜態庫)
動態框架
CocoaPod
Carthage
靜態框架(因為其他的需要些腳本)
Realm瀏覽器/數據庫管理器
官方提供了一個名為Realm Browser的Mac應用,用來進行Realm數? ? ? ? ? 據的讀取和編輯。(好用,但是每次編譯寫入新數據的時候,之前打開的會閃退)
Xcode 插件
怎么安裝就不贅述了,最開始的時候我會用,后來用多了,就自己手動建模型類了。
API手冊
能查詢Realm的完整版API手冊,里面包含了所有類和方法等信息。
示例
官方Demo里有(好多,而且是英文不是很懂)
數據模型(Model)
Realm數據模型是基于標準 Objective?C 類來進行定義的,使用屬性來完成模型的具體定義。
通過簡單的繼承RLMObject或者一個已經存在的模型類,您就可以創建一個新的 Realm 數據模型對象。
Realm模型對象在形式上基本上與其他 Objective?C 對象相同 - 您可以給它們添加您自己的方法(method)和協議(protocol),和在其他對象中使用類似。
主要的限制是某個對象只能在其被創建的那個線程中使用, 并且您無法訪問任何存儲屬性的實例變量(ivar)。
如果您安裝了我們的Xcode插件,那么可在”New File…“對話框中會有一個很漂亮的模板,可用來創建接口(interface)和執行(implementation)文件。
您只需要為對象的類型列表添加目標類型的屬性,或者RLMArray,就可以創建數據關系(relationship)和嵌套數據結構(nested data structure)。
我就不用官方文檔里的類說明了,以下就是實際項目(gitDemo)中類的創建以及使用
導入項目中的DataStore文件夾
拖進來之后(確保拖入時勾選了 Copy items if needed ),可能會報錯,查看報錯信息,(一般是缺少libc++.tbd)
建模型的基類
我將常用的數據庫操作已經做了封裝,在Store文件夾下是Realm數據庫的管理類,同時每個模型類都需要主鍵,所以應該抽象出父類來持有primaryKey和realmManager是有必要的。
模型類需要跟官方文檔里描述一致需要繼承RLMObject類RLM_ARRAY_TYPE(BasicRealm)定義一個RLMArray類型(不太明白的可以看一下官方源碼)
#import
#import"RLMObject+JSON.h"
#import"XMRealmStoreManager.h"
@interfaceBasicRealm :RLMObject
/**
*本地數據庫入庫的主鍵ID
*/
@property(nonatomic,copy)NSString*hostID;
/**
*? realm數據管理
*
*? @return realm數據管理
*/
+(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文件的具體方法請從項目中查看
建數據模型類
現在就可以根據項目需求建立明確的模型類,模型類需要繼承上述的基類BasicRealm。
假如現在的需求是Cell的標題下有三張圖片(大家自行腦補一下UI),那么我們需要標題屬性,以及一個圖片鏈接數組(Realm中不能用NSArray,需要用RLMArray)屬性聲明如下
#import"BasicModel.h"
RLM_ARRAY_TYPE(ImageRealm)//定義一個RLMArray類型
@interfaceDataRealm :BasicRealm
@property(nonatomic,copy)NSString*title;
@property(nonatomic,strong)RLMArray * image_url;
@end
@interfaceImageRealm :BasicRealm
@property(nonatomic,copy)NSString*image;
@end
.m中需要重寫兩個方法
+ (NSDictionary*)JSONInboundMappingDictionary(入庫的keyPath對應模型的keyPath)
+ (NSDictionary*)JSONOutboundMappingDictionary(出庫的keyPath對應模型的keyPath)
兩個方法一般內容都相同,一般我們寫的模型類都是基于服務器返回數據的KeyPath作為我們數據類的屬性名。但當服務器返回的數據(比如服務器數據庫的主鍵是id,當然你也可以跟服務端開發商量一下提前做一下key的更改,畢竟好兄弟~)有一些OC的關鍵詞比如id這樣的話我們就需要將入(出)庫的keyPath對應模型的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數據模型類的使用
用Realm管理類調用數據的增刪改差
//增or改
-(void)add
{
[[DataRealmrealmManager]writeObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//在這返回一個id對象可以是一個包含多個數據庫模型的數組,也可以是單個數據庫模型對象可以調用Real自己的解析字典方法,也可以用封裝好的方法(根據服務器返回的數據類型)
return[DataRealmcreateOrUpdateInRealm:realmwithJSONDictionary:@{@"hostID":@"1",@"title":@"好好學習天天向上",@"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) {
//事務完成后回調
}];
}
//刪
-(void)delete{
[[DataRealmrealmManager]deleteObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//可以根據sql語句查找刪除
return[DataRealmobjectsWhere:@""];
//也可以根據主鍵獲得
return[DataRealmobjectForPrimaryKey:@"1"];
}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm) {
//事務完成回調
}];
}
//查
-(void)search
{
[[DataRealmrealmManager]fetchObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {
//可以根據sql語句查找刪除
return[DataRealmobjectsWhere:@""];
//也可以根據主鍵獲得
return[DataRealmobjectForPrimaryKey:@"1"];
}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm,RLMResults*results,NSString*primaryKey,NSMutableArray*models) {
//事務完成回調獲得查詢內容更新UI
}];
}
后語:
我建議大家將數據分為兩種類,一種是數據庫類,一種是平常我們不做數據存儲的類(我在Demo(由于git文件大小限制不能上傳Realm.framework,請大家自行拖入)中是這樣操作的)。這樣做的好處是分開來易于管理,那些屬性內容需要入庫就在數據庫類中聲明,不需要的但是我們UI展示上需要的在單獨的數據類中。這樣數據庫中就不需要冗余的key(當然也可以通過.m的兩種方法來控制入庫的keyPath)這樣做還有一個不算原因的原因,這樣做可以用一些字典轉模型的解析類框架(比如MJ,YYModel等)。總是這項看個人喜好吧。