? ? ? ?目測現在開發人員用的最多存儲方式應該就是FMDB與Coredata。但用過Coredata的開發人員應該知道coredata的使用并非很方便。So,用第三方的應該占大多數。今天就說下Coredata的第三庫:MagicalRecord;
本篇文章只介紹MagicalRecord初始化與數據遷移兩個知識點。還有一個是提供了一個提前預制數據庫的邏輯思路。因本人所負責的項目就有這種需求,所以這里貼出來供大家探討。
以下簡稱MagicalRecord為MR。
MR 初始化主要分為一下四類:
一,以程序名為數據庫名,不需要自動升級
[MagicalRecord setupCoreDataStack];
二,以程序名為數據庫名,需要自動升級
[MagicalRecord setupAutoMigratingCoreDataStack];
三,自定義數據庫名,不需要自動升級
[MagicalRecord setupCoreDataStackWithStoreNamed:@"LocalModel.sqlite"];
四,自定義數據庫名,需要自動升級
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"LocalModel.sqlite"];
我們知道,在使用Coredata的時候,系統會默認生成一些代碼,同時生成數據庫存儲路徑,同樣是以程序名命名。所以,MR的默認命名也是以程序名命名。無論何種命名,默認的路徑都是在Library目錄下。
由此可知,初始化MR使用哪一種方式都可以,當然,長遠考慮還是用可以自動升級數據庫的方式更好。以后如果字段變更,結構變更,已安裝用戶需要升級時,處理起來就相當方便。下面就來說下數據庫自動升級。
假設已經用可自動升級方式初始化了MR,運行時先存入一條數據(MR引入,model創建,不在贅述):
找到數據庫位置并打開,可以看到:
數據已存入表中。假設app已經推廣并有用戶使用,這時增加需求,需要給User加個age字段。這時候MR自動升級的優勢就來了:
1,先新建一個模型文件的新版本,命名默認即可
2,添加完成后可以看到原來只有一個的LocalModel.xcdatamodeld左側多了個三角,點開可看到新建的version。現在給新的model文件中的User實體添加age字段。
3,如果仔細觀察,可以看到左側model文件中有個綠色的對勾,并未勾選在新建的version上面,說明新建的version并非當前模型文件,需要把他選為當前模型文件。
4,根據新的model文件生成新的實體類
好的,升級完成,下面進行測試,新插入一條數據進行測試,在打開數據庫看下:
OK,新數據已經插入,原來的數據也沒有丟失,至此,升級完成。但在代碼中切記判斷age字段是否是 Null。
下面簡單說下數據庫預制。
什么情況下需要提前預制數據庫,想想就知道,但總結來說,就是本地常用的數據,大量的,固定不變的,不適合通過網絡獲取的,都可以提前預制到數據庫。整體思路如下(假設利用模擬器):
1,根據預制需要,先生成相應的數據表;
2,利用死代碼,把需要預制的數據存入表中(這里執行的方法切勿在程序正常使用時執行,只適合打包前,也就是預制時使用一次);
3,找到生成的數據庫文件,剪切到工程目錄中并刪除模擬器中的app應用;
4,利用NSFileManager把工程目錄中的數據庫文件復制到Document目錄或者Library目錄下;
5,利用MR正常生成數據庫,必須寶成此時生成的數據庫文件名字與提前預制的一致,這樣,MR自動會利用提前預制的數據庫;(正常情況下,這種方式只需要在用戶初次安裝時用到,記得做判斷哦)
6,預制成功,繼續自己的工作。
下面是我的demo中的預制數據庫的代碼部分,僅供參考:
下面列出一些常用方法,具體使用不在贅述:
1,查詢所有文件
+ (NSArray *) MR_findAll;
2,根據某個屬性(字段)查詢文件,是否升序(例如根據age 屬性升序或降序查詢)
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;
3,根據某個屬性(字段)查詢文件,是否升序,是否有其他限制(比如:根據age升序查詢,限制為:name = @"Lili')
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm;
//舉例
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",@"Lili"];
NSArray *resultArr = [User MR_findAllSortedBy:@"age" ascending:YES withPredicate:predicate];
4,直接根據某個限制查詢
+ (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm;
5,查詢所有實體 //根據上下文
+ (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context
+ (NSArray *) MR_findAll
不一一舉例了。更多請查看 NSManagedObject+MagicalFinders.h ?頭文件。
tips:
MR每一步都有NSLog輸出,關閉輸出的方式:把 MagicalRecord.h 中第 23行改為 1
有用無用,請砸來閣下的意見,謝謝!