MagicalRecord

MagicalRecord

iOS 开发过程中,经常采用CoreData来进行数据持久化。但在使用CoreData进行存取等操作时,代码量相对较多。而 MagicalRecord 正是为方便操作 CoreData 而生。

MagicalRecord 的三个目标:

  1. 简化 CoreData 相关代码
  2. 清晰、简单、单行获取数据
  3. 当需要优化请求的时候,仍然允许修改 NSFetchRequest

1. 配置

使用 CocoaPods 安装后,在文件中导入:#import <MagicalRecord/CoreData+MagicalRecord.h>后即可使用。 第一步:在- applicationDidFinishLaunching: withOptions:-awakeFromNib方法中,使用MagicalRecord类方法设置:

’+ (void)setupCoreDataStack;

  • (void)setupAutoMigratingCoreDataStack;
  • (void)setupCoreDataStackWithInMemoryStore;
  • (void)setupCoreDataStackWithStoreNamed:(NSString *)storeName;
  • (void)setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
  • (void)setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL;
  • (void)setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL;’

上述方法会实例化一个Core Data stack

在程序退出的时候调用类方法+cleanUp类清除MagicalRecord的配置。

[MagicalRecord cleanUp];

如果为了利用苹果 iCloud Core Data 同步,可以调用以下的方法。

+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID localStoreNamed:(NSString *)localStore; + (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; + (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void (^)(void))completion; + (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID localStoreAtURL:(NSURL *)storeURL; + (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent; `+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void (^)(void))completion;’

2. 创建 Entity【插入到 managedObjectContext】:

Person *myPerson = [Person MR_createEntity];默认的 context Person *myPerson = [Person MR_createEntityInContext:otherContext];特定的 context

3. 删除 Entity【从managedObjectContext 中删除】:

[myPerson MR_deleteEntity]; [myPerson MR_deleteEntityInContext:otherContext]; [Person MR_truncateAll];删除所有 Entity [Person MR_truncateAllInContext:otherContext];

4. 查询 Entity

基础查询:返回的结果通常是NSArray

NSArray *people = [Person MR_findAll]; NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName" ascending:YES]; NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName" ascending:YES]; NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName:NO,FirstName" ascending:YES]; Person *person = [Person MR_findFirstByAttribute:@"FirstName" withValue:@"Forrest"];//键值条件查找,返回符合条件的所有数据

高级查询:使用NSPredicate

NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]]; NSArray *people = [Person MR_findAllWithPredicate:peopleFilter];

返回NSFetchRequest:可以自定义NSFetchRequest来进行特定查找

// 返回 NSFetchRequest
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter];
// 自定义 NSFetchRequest
[peopleRequest setReturnsDistinctResults:NO];
[peopleRequest setReturnPropertiesNamed:@[@"FirstName", @"LastName"]];
NSArray *people = [Person MR_executeFetchRequest:peopleRequest];

返回 Entity 的数量

NSNumber *count = [Person MR_numberOfEntities]; NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...];

聚合操作

// 聚合操作
NSNumber *totalCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
                                                  onAttribute:@"calories"
                                                withPredicate:predicate];

NSNumber *mostCalories  = [CTFoodDiaryEntry MR_aggregateOperation:@"max:"
                                                  onAttribute:@"calories"
                                                withPredicate:predicate];

NSArray *caloriesByMonth = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
                                                   onAttribute:@"calories"
                                                 withPredicate:predicate
                                                       groupBy:@"month"];

5. 保存 Entity

// NSManagedObjectContext+MagicalSaves
+ (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; // Asynchronously
+ (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion; // Asynchronously
+ (void) MR_saveOnlySelfAndWait; // Synchronously
+ (void) MR_saveToPersistentStoreAndWait; // Synchronously
+ (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;

// MagicalRecord+Actions
* (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block; // Asynchronously
* (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; // Asynchronously
* (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;
* (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
* (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;

下面看一个实例:

// 0. setup
[MagicalRecord setupCoreDataStackWithStoreNamed:@"Model"];

// 1. insert
for (int i = 1; i < 5; i++) {
    Person* p = [Person MR_createEntity];
    p.name = [NSString stringWithFormat:@"p%d", i];
    p.age = [NSNumber numberWithInt:i];
}

// 2. delete
Person* pd = [Person MR_findFirst];
[pd MR_deleteEntity];

// 3. update
Person* pu = [Person MR_findFirstByAttribute:@"name" withValue:@"p2"];
pu.name = @"p22";

// 4. save
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError* error) {
    if (success) {
        NSLog(@"***save success!***");
    }
    else {
        NSLog(@"***save failure!***");
    }
}];

上述主要讲了如何使用MagicalRecord来简化 CoreData 操作的代码,下一篇将主要介绍如何使用MagicalRecord向 CoreData 导入 JSON 数据

参考

http://segmentfault.com/blog/lingchen/1190000002431365 http://www.raywenderlich.com/56879/magicalrecord-tutorial-ios

Loading Disqus comments...
Table of Contents