Mantle with CoreData

PS:网上流传的最多的一篇关于Mantle的文章,但是大家都没注明作者,有谁知道的可以留言下,我会补充上去。

Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application.  Mantle can still be a convenient translation layer between the API and your managed model objects.

本文使用mantle作data model,并使用其对coredata的interface创建数据持久化的过程。

操作过程很简单,就是数据的转换:

1.Manle data model

Mantle中用于持久化的方法:

// A MTLModel object that supports being serialized to and from Core Data as an

// NSManagedObject.

  • @protocol MTLManagedObjectSerializing

  • @required

// The name of the Core Data entity that the receiver serializes to and

// deserializes from.

  • + (NSString *)managedObjectEntityName;

// Specifies how to map property keys to different keys on the receiver's

// +managedObjectEntity.

  • + (NSDictionary *)managedObjectKeysByPropertyKey;

.h 文件

#import <Foundation/Foundation.h>  
  
@interface BannerWrapper : MTLModel <MTLJSONSerializing,MTLManagedObjectSerializing>  
  
@property (nonatomic, readonly) bool result;  
@property (copy, nonatomic, readonly) NSNumber *resultId;  
@property (copy, nonatomic, readonly) NSString *resultMsg;  
@property (copy, nonatomic) NSArray *bannerList;  
+(NSSortDescriptor *)sortDescriptor;  
@end  
  
@interface Banner : MTLModel <MTLJSONSerializing, MTLManagedObjectSerializing>  
  
@property (copy, nonatomic, readonly) NSNumber *bannerId;  
@property (copy, nonatomic, readonly) NSString *picUrl;  
@property (copy, nonatomic, readonly) NSString *toDetailUrl;  
@property (copy, nonatomic, readonly) NSNumber *width;  
@property (copy, nonatomic, readonly) NSNumber *height;  
  
@end  

.m文件

#import "Banner.h"  
  
@implementation BannerWrapper  
  
#pragma mark - JSON serialization  
  
+ (NSDictionary *)JSONKeyPathsByPropertyKey {  
    return @{  
             @"result" : @"result",  
             @"resultId" : @"resultId",  
             @"resultMsg" : @"resultMSG",  
             @"bannerList" : @"banner"  
             };  
}  
  
+ (NSValueTransformer *)bannerListJSONTransformer  
{  
    return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:[Banner class]];  
}  
  
#pragma mark - Managed object serialization  
  
+ (NSString *)managedObjectEntityName {  
    return @"BannerWrapper";  
}  
  
+ (NSDictionary *)managedObjectKeysByPropertyKey {  
    return nil;  
}  
  
+(NSDictionary *)relationshipModelClassesByPropertyKey{  
    return @{  
             @"bannerList"  : [Banner class],  
             };  
}  
  
//在从coredata中取数据时的数据排序方式  
+(NSSortDescriptor *)sortDescriptor{  
    return [[NSSortDescriptor alloc] initWithKey:@"resultId" ascending:YES];  
}  
  
@end  
  
@implementation Banner  
  
#pragma mark - JSON serialization  
  
+ (NSDictionary *)JSONKeyPathsByPropertyKey {  
    return @{  
             @"bannerId" : @"id",  
             @"picUrl" : @"picUrl",  
             @"toDetailUrl" : @"toDetailUrl",  
             @"width":@"width",  
             @"height":@"height"  
             };  
}  
  
#pragma mark - Managed object serialization  
  
+ (NSString *)managedObjectEntityName {  
    return @"Banner";  
}  
  
+ (NSDictionary *)managedObjectKeysByPropertyKey {  
    return nil;  
}  
  
@end  

2.Coredata 持久化类

Coredata主要元素简要介绍

网上有很多图,但,还是觉得一本书上的这个图最好:

  • 1, Managed Object Model
    Managed Object Model 是描述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request)等。(下文都使用英文术语。)

    2,Managed Object Context
    Managed Object Context 参与对数据对象进行各种操作的全过程,并监测数据对象的变化,以提供对 undo/redo 的支持及更新绑定到数据的 UI。

    3,Persistent Store Coordinator
    Persistent Store Coordinator 相当于数据文件管理器,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。

    4,Managed Object
    Managed Object 数据对象,与 Managed Object Context 相关联。


  • 5,Controller
    图中绿色的 Array Controller, Object Controller, Tree Controller 这些控制器,一般都是通过 control+drag 将 Managed Object Context 绑定到它们,这样我们就可以在 nib 中可视化地操作数据。

.h文件

#import <Foundation/Foundation.h>  
  
@interface Persistence : NSObject  
  
//数据模型对象  
@property(strong,nonatomic) NSManagedObjectModel *managedObjectModel;  
//上下文对象  
@property(strong,nonatomic) NSManagedObjectContext *managedObjectContext;  
//持久性存储区  
@property(strong,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;  
  
//确定sqlite文件存储路径  
-(NSURL *)storeURL;  
  
//初始化Core Data使用的数据库  
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator;  
  
//managedObjectModel的初始化赋值函数  
-(NSManagedObjectModel *)managedObjectModel;  
  
//managedObjectContext的初始化赋值函数  
-(NSManagedObjectContext *)managedObjectContext;  
  
//保存MTLModel对象至coredata  
-(BOOL)saveMTLModel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
              error:(NSError * __autoreleasing *)error;  
  
//从coredata中提取出MTLModel  
-(MTLModel *)getMTLmodel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
                   error:(NSError *__autoreleasing *)error;  
  
//+ (NSFetchRequest *)fetchRequest;  
@end

.m文件

#import "Persistence.h"  
  
@implementation Persistence  
  
@synthesize managedObjectContext;  
@synthesize managedObjectModel;  
@synthesize persistentStoreCoordinator;  
  
  
//确定sqlite文件存储路径  
-(NSURL *)storeURL{  
    //得到数据库的路径  
    //    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
    //    //CoreData是建立在SQLite之上的,数据库名称需与Xcdatamodel文件同名  
    //    NSURL *storeUrl = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"CoreData.sqlite"]];  
      
    NSArray *documnetDir=NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);  
    NSString *docDir=[documnetDir objectAtIndex:0];  
    NSString *path=[docDir stringByAppendingPathComponent:@"CoreData.sqlite"];  
    NSURL *storeURL=[NSURL fileURLWithPath:path];  
    return storeURL;  
}  
  
  
//初始化Core Data使用的数据库  
-(NSManagedObjectModel *)managedObjectModel  
{  
    if (managedObjectModel != nil) {  
        return managedObjectModel;  
    }  
    return [NSManagedObjectModel mergedModelFromBundles:nil];  
}  
  
//managedObjectModel的初始化赋值函数  
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator  
{  
    if (persistentStoreCoordinator != nil) {  
        return persistentStoreCoordinator;  
    }  
      
    NSError *error = nil;  
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]  
                                  initWithManagedObjectModel:self.managedObjectModel];  
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType  
                                                  configuration:nil  
                                                            URL:[self storeURL]  
                                                        options:nil  
                                                          error:&error]) {  
        NSLog(@"Error: %@,%@",error,[error userInfo]);  
        [NSException raise:@"open failed" format:@"Reason:%@",[error localizedDescription]];  
    }  
      
    return persistentStoreCoordinator;  
}  
  
//managedObjectContext的初始化赋值函数  
-(NSManagedObjectContext *)managedObjectContext  
{  
    if (managedObjectContext != nil) {  
        return managedObjectContext;  
    }  
      
    NSPersistentStoreCoordinator *coordinator =self.persistentStoreCoordinator;  
      
    if (coordinator != nil) {  
        managedObjectContext = [[NSManagedObjectContext alloc]init];  
        [managedObjectContext setPersistentStoreCoordinator:coordinator];  
    }  
      
    return managedObjectContext;  
}  
  
//保存MTLModel对象至coredata  
-(BOOL)saveMTLModel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
              error:(NSError *__autoreleasing *)error{  
    //-----Need Add Remove the Entity First  START---------  
    NSManagedObject *exsitManagedObject=[self getManagedObject:mtlModel  
                                                         error:error];  
    if (exsitManagedObject!=nil) {  
        [self.managedObjectContext deleteObject:exsitManagedObject];  
        [self.managedObjectContext save:error];  
    };  
    //-----Need Add Remove the Entity First  END-----------  
      
    NSManagedObject *managedObject = [MTLManagedObjectAdapter  
                                      managedObjectFromModel:mtlModel  
                                      insertingIntoContext:self.managedObjectContext  
                                      error:error];  
      
    if (managedObject==nil) {  
        NSLog(@"[NSManagedObject] Error:%@",*error);  
        return NO;  
    }  
      
    if (![self.managedObjectContext save:error]) {  
        NSLog(@"[self.managedObjectContext] Error:%@",*error);  
        return NO;  
    };  
    return YES;  
};  
  
//从coredata中提取出MTLModel  
-(MTLModel *)getMTLmodel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
                   error:(NSError *__autoreleasing *)error{  
      
    NSManagedObject *managedObject=[self getManagedObject:mtlModel error:error];  
    MTLModel *mrlMotel=[[MTLModel alloc] init];  
      
    mrlMotel = [MTLManagedObjectAdapter modelOfClass:[mtlModel class]  
                                   fromManagedObject:managedObject error:error];  
      
    if (error) {  
        NSLog(@"[mrlMotel] Error:%@",*error);  
    }  
    return mrlMotel;  
};  
  
//从coredata中获取已存的ManagedObject  
-(NSManagedObject *)getManagedObject:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
                               error:(NSError *__autoreleasing *)error{  
    NSString *entityName=[[mtlModel class] managedObjectEntityName];  
      
    //获取entity中对象数量  
    NSFetchRequest *requestCount=[NSFetchRequest fetchRequestWithEntityName:entityName];  
    NSUInteger count=[self.managedObjectContext countForFetchRequest:requestCount  
                                                               error:error];  
    NSLog(@"count result:%d",count);  
    NSLog(@"sortDescriptor result:%@",[[mtlModel class] sortDescriptor]);  
      
    //获取entity中第一个对象.这个对象必须存在且唯一。  
    if (count==1) {  
        NSFetchRequest *request=[[NSFetchRequest alloc] init];  
        [request setEntity:[NSEntityDescription entityForName:entityName  
                                       inManagedObjectContext:self.managedObjectContext]];  
        NSSortDescriptor *sort=[[mtlModel class] sortDescriptor];  
        NSArray *sortDes=[[NSArray alloc] initWithObjects:sort, nil nil];  
        [request setSortDescriptors:sortDes];  
        NSArray *getObject=[self.managedObjectContext  
                            executeFetchRequest:request  
                            error:error];  
          
        return [getObject objectAtIndex:0];  
    }  
    return nil;  
}  
  
//从文件系统中删除sqlite文件  
-(bool)deleteAllEntities{  
    bool status=NO;  
    NSError *error;  
    @try{  
        [[NSFileManager defaultManager] removeItemAtPath:[self storeURL].path  
                                                   error:&error];  
        status=YES;  
    }  
    @catch (NSException *exception) {  
        status=NO;  
    }  
    @finally {  
        return status;  
    }  
}  
  
@end  

3.后台执行程序

-------------Persistence DEMO---------------------  
        //If network error, get data from CoreData, else save data into CoreData  
        if (!error) {  
            NSError *err;  
            Persistence *persistence=[[Persistence alloc] init];  
            BOOL save=[persistence saveMTLModel:responseObject error:&err];  
            if (save==NO) {  
                NSLog(@"Save ERROR!");  
            }  
        }else{  
            NSError *err;  
            Persistence *persistence=[[Persistence alloc] init];  
            BannerWrapper *resObject=[[BannerWrapper alloc] init];  
            BannerWrapper *object=[[BannerWrapper alloc] init];  
            object=[persistence getMTLmodel:resObject error:&err];  
  
            responseObject=object;  
              
            //这个地方异常的奇怪,从coredata中应该返回打Array类型变成了set类型,所以这里暂时作了一个转换。  
            if ([object.bannerList isKindOfClass:[NSSet class]]) {  
                NSArray *objectArray = [(NSSet *)object.bannerList  allObjects];  
                ((BannerWrapper *)responseObject).bannerList=objectArray;  
            }  
        }  
        //-----------------------------------------------------------  
          
        BannerWrapper *wrapper = responseObject;  
        block(wrapper.bannerList, error);  
          
    }];  
}  


 

猜你喜欢

转载自blog.csdn.net/Ginhoor/article/details/41441309
今日推荐