Mantle with CoreData

来源:互联网 发布:golang java 性能对比 编辑:程序博客网 时间:2024/06/05 07:03

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)等。(下文都使用英文术语。)

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

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

    4Managed 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);                }];  }  


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



0 0