MagicalRecord配合Mantle

在开始之前,我们先创建一个名为MemberManaged的实体MagicalRecord配合Mantle_第1张图片

MemberManaged.h

@interface MemberManaged : NSManagedObject 
@property ( nonatomic, retain) NSString * memberID;
@property ( nonatomic, retain) NSString * mobilePhone;
@property ( nonatomic, retain) NSDate * createDate;
@property ( nonatomic, retain) NSNumber * goldNumber;
@property ( nonatomic, retain) NSNumber * age;
@property ( nonatomic, retain) NSNumber * isVip;
@property ( nonatomic, retain) NSString * url;

快速入门后续的例子都是以此实体进行数据库的操作

配置

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[MagicalRecord setupAutoMigratingCoreDataStack];
// ... 
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
[MagicalRecord cleanUp];
}

查找数据

//返回MemberManaged表中的第一条数据 
MemberManaged *memberManaged = [MemberManaged MR_findFirst];
//返回MemberManaged表中的所有数据 
NSArray *array = [[MemberManaged MR_findAll];
//键值条件查找,返回符合条件的所有数据 
NSArray *array = [MemberManaged MR_findByAttribute:@ "memberID" withValue:@ "1"];
//按指定字段排序 
NSArray *array = [MemberManaged MR_findAllSortedBy: @"age" ascending: YES];
//自定义NSPredicate查找,返回符合条件的所有数据 
NSPredicate *pre = [NSPredicate predicateWithFormat:@ "age > 18"];
MemberManaged *memberManaged = [MemberManaged MR_findAllWithPredicate:pre];

插入数据

对于NSPredicate不熟悉的同学可以看我之前写的介绍NSPredicate的博文,关于其他的查找方法我就不一一介绍了。

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    MemberManaged *memberManaged = [MemberManaged MR_createInContext:localContext];
    memberManaged.memberID = @"1";
    memberManaged.mobilePhone = @"xxxxxxxx";
    memberManaged.createDate = [NSDate date];
    memberManaged.goldNumber = @2;
    memberManaged.age = @18;
    memberManaged.url = @"http://bawn.github.io/";
    memberManaged.isVip = @YES;
    
} completion:^(BOOL success, NSError *error) {
    // ...
}];

删除数据

//删除单条数据
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
MemberManaged *member = [MemberManaged MR_findFirstInContext:localContext];
[member MR_deleteEntity];
} completion:^(BOOL success, NSError *error) {
// ... 
}];
//删除表
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
[MemberManaged MR_truncateAllInContext:localContext];
} completion:^(BOOL success, NSError *error) {
// ... 
}];

更新数据

MemberManaged *member = [MemberManaged MR_findFirst];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    MemberManaged *localMember = [member MR_inContext:localContext];
    localMember.age = @22;
} completion:^(BOOL success, NSError *error) {
    // ...
}];

为什么不用[NSManagedObjectContext save:]方法,请看博客

配合Mantle

基本转换

上一篇博文中提到Mantle的<MTLManagedObjectSerializing>协议,此协议有两个必须实现的方法:

//返回此类对应的实体类名
+ (NSString *)managedObjectEntityName;
//返回此类和实体属性的映射关系
+ (NSDictionary *)managedObjectKeysByPropertyKey;

另外由于Member类和MemberManaged类的url字段的类型不一致,需要实现另一个协议方法,实现NSUrl—>NSString(age和isVip字段不需要转换,不要问我为什么)

//属性值转换
+ (NSValueTransformer *)entityAttributeTransformerForKey:(NSString *)key;

先看具体实现

Member.h

@interface Member : MTLModel<MTLJSONSerializing, MTLManagedObjectSerializing>
@property (nonatomic, retain) NSString * memberID;
@property (nonatomic, retain) NSString * mobilePhone;
@property (nonatomic, retain) NSDate * createDate;
@property (nonatomic, retain) NSNumber *goldNumber;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) BOOL isVip;
@property (nonatomic, retain) NSURL *url;

Member.m

//表示Member类对应的实体类是MemberManaged
+ (NSString *)managedObjectEntityName{
    return @"MemberManaged";
}
//表示Member类向MemberManaged类转换的字段映射,因为Member类的字段名是相同,所以这里返回nil
+ (NSDictionary *)managedObjectKeysByPropertyKey{
    return nil;
}
//表示Member的url向MemberManaged的url字段值转换
+ (NSValueTransformer *)entityAttributeTransformerForKey:(NSString *)key{
    if ([key isEqualToString:@"url"]) {
        return [MTLValueTransformer reversibleTransformerWithBlock:^id(NSURL *url) {
            return url.absoluteString;
        }];
    }
    else{
        return nil;
    }
}

具体运用:

NSDictionary *dic = @{@"id" : @"1",
                      @"phone" : @"xxxxxxxx",
                      @"date" : @"2014-09-09",
                      @"goldNumber" : @2,
                      @"age" : @"28",
                      @"url" : @"http://bawn.github.io/",
                      @"isVip" : NSNull.null
                      };
Member *member = [MTLJSONAdapter modelOfClass:[Member class] fromJSONDictionary:dic error:nil];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    [MTLManagedObjectAdapter managedObjectFromModel:member insertingIntoContext:localContext error:nil];
} completion:^(BOOL success, NSError *error) {
    NSLog(@"%@", [(MemberManaged *)[MemberManaged MR_findFirst] isVip]);
}];
  1. Member *member = [MTLJSONAdapter modelOfClass:[Member class] fromJSONDictionary:dic error:nil];完成从NSDictionary—>Member转换,并返回Member实例
  2. [MTLManagedObjectAdapter managedObjectFromModel:member insertingIntoContext:localContext error:nil];完成Member—>MemberManaged转换,返回MemberManaged实例,但是我们并不需要。
  3. 配合MagicalRecord储存方法+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;

注意:对于MemberManaged类,我们并不需要对它做任何的处理。

唯一性检查

同样是实现<MTLManagedObjectSerializing>中的一个方法:

+ (NSSet *)propertyKeysForManagedObjectUniquing{
    return [NSSet setWithObject:@"memberID"];
}

执行一下代码表示当插入新数据的时候,对比需要插入的这条数据的memberID字段的值是否和数据库中的有相同。如果有相同就覆盖更新这条数据,如果没有就新增。这样带来的方便之处显而易见。

for (int n = 0; n < 2; n++) {
      NSDictionary *dic = @{@"id" : @"1",
                            @"phone" : @"xxxxxxxx",
                            @"date" : @"2014-09-09",
                            @"goldNumber" : @2,
                            @"age" : @"18",
                            @"url" : @"http://bawn.github.io/",
                            @"isVip" : NSNull.null
                            };
      
      Member *member = [MTLJSONAdapter modelOfClass:[Member class] fromJSONDictionary:dic error:nil];
      [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
          [MTLManagedObjectAdapter managedObjectFromModel:member insertingIntoContext:localContext error:nil];
      } completion:^(BOOL success, NSError *error) {
          NSLog(@"%d", [(MemberManaged *)[MemberManaged MR_findFirst] isVip].boolValue);
      }];
  }

数据库中只有一条数据,因为插入的数据的memberID都是2。

总结

MagicalRecord配合Mantle使用至少让代码看起来简洁了不少,再也不用为Core Data复杂的API而烦恼,也不用再写if/else来做字段的转换。

Demo地址:MagicalRecord-Mantle

你可能感兴趣的:(MagicalRecord配合Mantle)