• Core Data with 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创建数据持久化的过程。

    操作过程非常easy。就是数据的转换:


    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 文件

    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface BannerWrapper : MTLModel <MTLJSONSerializing,MTLManagedObjectSerializing>  
    4.   
    5. @property (nonatomicreadonlybool result;  
    6. @property (copynonatomicreadonlyNSNumber *resultId;  
    7. @property (copynonatomicreadonlyNSString *resultMsg;  
    8. @property (copynonatomicNSArray *bannerList;  
    9. +(NSSortDescriptor *)sortDescriptor;  
    10. @end  
    11.   
    12. @interface Banner : MTLModel <MTLJSONSerializing, MTLManagedObjectSerializing>  
    13.   
    14. @property (copynonatomicreadonlyNSNumber *bannerId;  
    15. @property (copynonatomicreadonlyNSString *picUrl;  
    16. @property (copynonatomicreadonlyNSString *toDetailUrl;  
    17. @property (copynonatomicreadonlyNSNumber *width;  
    18. @property (copynonatomicreadonlyNSNumber *height;  
    19.   
    20. @end  


    .m文件

    1. #import "Banner.h"  
    2.   
    3. @implementation BannerWrapper  
    4.   
    5. #pragma mark - JSON serialization  
    6.   
    7. + (NSDictionary *)JSONKeyPathsByPropertyKey {  
    8.     return @{  
    9.              @"result" : @"result",  
    10.              @"resultId" : @"resultId",  
    11.              @"resultMsg" : @"resultMSG",  
    12.              @"bannerList" : @"banner"  
    13.              };  
    14. }  
    15.   
    16. + (NSValueTransformer *)bannerListJSONTransformer  
    17. {  
    18.     return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:[Banner class]];  
    19. }  
    20.   
    21. #pragma mark - Managed object serialization  
    22.   
    23. + (NSString *)managedObjectEntityName {  
    24.     return @"BannerWrapper";  
    25. }  
    26.   
    27. + (NSDictionary *)managedObjectKeysByPropertyKey {  
    28.     return nil;  
    29. }  
    30.   
    31. +(NSDictionary *)relationshipModelClassesByPropertyKey{  
    32.     return @{  
    33.              @"bannerList"  : [Banner class],  
    34.              };  
    35. }  
    36.   
    37. //在从coredata中取数据时的数据排序方式  
    38. +(NSSortDescriptor *)sortDescriptor{  
    39.     return [[NSSortDescriptor alloc] initWithKey:@"resultId" ascending:YES];  
    40. }  
    41.   
    42. @end  
    43.   
    44. @implementation Banner  
    45.   
    46. #pragma mark - JSON serialization  
    47.   
    48. + (NSDictionary *)JSONKeyPathsByPropertyKey {  
    49.     return @{  
    50.              @"bannerId" : @"id",  
    51.              @"picUrl" : @"picUrl",  
    52.              @"toDetailUrl" : @"toDetailUrl",  
    53.              @"width":@"width",  
    54.              @"height":@"height"  
    55.              };  
    56. }  
    57.   
    58. #pragma mark - Managed object serialization  
    59.   
    60. + (NSString *)managedObjectEntityName {  
    61.     return @"Banner";  
    62. }  
    63.   
    64. + (NSDictionary *)managedObjectKeysByPropertyKey {  
    65.     return nil;  
    66. }  
    67.   
    68. @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文件

    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface Persistence : NSObject  
    4.   
    5. //数据模型对象  
    6. @property(strong,nonatomicNSManagedObjectModel *managedObjectModel;  
    7. //上下文对象  
    8. @property(strong,nonatomicNSManagedObjectContext *managedObjectContext;  
    9. //持久性存储区  
    10. @property(strong,nonatomicNSPersistentStoreCoordinator *persistentStoreCoordinator;  
    11.   
    12. //确定sqlite文件存储路径  
    13. -(NSURL *)storeURL;  
    14.   
    15. //初始化Core Data使用的数据库  
    16. -(NSPersistentStoreCoordinator *)persistentStoreCoordinator;  
    17.   
    18. //managedObjectModel的初始化赋值函数  
    19. -(NSManagedObjectModel *)managedObjectModel;  
    20.   
    21. //managedObjectContext的初始化赋值函数  
    22. -(NSManagedObjectContext *)managedObjectContext;  
    23.   
    24. //保存MTLModel对象至coredata  
    25. -(BOOL)saveMTLModel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
    26.               error:(NSError * __autoreleasing *)error;  
    27.   
    28. //从coredata中提取出MTLModel  
    29. -(MTLModel *)getMTLmodel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
    30.                    error:(NSError *__autoreleasing *)error;  
    31.   
    32. //+ (NSFetchRequest *)fetchRequest;  
    33. @end  




    .m文件

    1. #import "Persistence.h"  
    2.   
    3. @implementation Persistence  
    4.   
    5. @synthesize managedObjectContext;  
    6. @synthesize managedObjectModel;  
    7. @synthesize persistentStoreCoordinator;  
    8.   
    9.   
    10. //确定sqlite文件存储路径  
    11. -(NSURL *)storeURL{  
    12.     //得到数据库的路径  
    13.     //    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
    14.     //    //CoreData是建立在SQLite之上的。数据库名称需与Xcdatamodel文件同名  
    15.     //    NSURL *storeUrl = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"CoreData.sqlite"]];  
    16.       
    17.     NSArray *documnetDir=NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);  
    18.     NSString *docDir=[documnetDir objectAtIndex:0];  
    19.     NSString *path=[docDir stringByAppendingPathComponent:@"CoreData.sqlite"];  
    20.     NSURL *storeURL=[NSURL fileURLWithPath:path];  
    21.     return storeURL;  
    22. }  
    23.   
    24.   
    25. //初始化Core Data使用的数据库  
    26. -(NSManagedObjectModel *)managedObjectModel  
    27. {  
    28.     if (managedObjectModel != nil) {  
    29.         return managedObjectModel;  
    30.     }  
    31.     return [NSManagedObjectModel mergedModelFromBundles:nil];  
    32. }  
    33.   
    34. //managedObjectModel的初始化赋值函数  
    35. -(NSPersistentStoreCoordinator *)persistentStoreCoordinator  
    36. {  
    37.     if (persistentStoreCoordinator != nil) {  
    38.         return persistentStoreCoordinator;  
    39.     }  
    40.       
    41.     NSError *error = nil;  
    42.     persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]  
    43.                                   initWithManagedObjectModel:self.managedObjectModel];  
    44.     if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType  
    45.                                                   configuration:nil  
    46.                                                             URL:[self storeURL]  
    47.                                                         options:nil  
    48.                                                           error:&error]) {  
    49.         NSLog(@"Error: %@,%@",error,[error userInfo]);  
    50.         [NSException raise:@"open failed" format:@"Reason:%@",[error localizedDescription]];  
    51.     }  
    52.       
    53.     return persistentStoreCoordinator;  
    54. }  
    55.   
    56. //managedObjectContext的初始化赋值函数  
    57. -(NSManagedObjectContext *)managedObjectContext  
    58. {  
    59.     if (managedObjectContext != nil) {  
    60.         return managedObjectContext;  
    61.     }  
    62.       
    63.     NSPersistentStoreCoordinator *coordinator =self.persistentStoreCoordinator;  
    64.       
    65.     if (coordinator != nil) {  
    66.         managedObjectContext = [[NSManagedObjectContext alloc]init];  
    67.         [managedObjectContext setPersistentStoreCoordinator:coordinator];  
    68.     }  
    69.       
    70.     return managedObjectContext;  
    71. }  
    72.   
    73. //保存MTLModel对象至coredata  
    74. -(BOOL)saveMTLModel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
    75.               error:(NSError *__autoreleasing *)error{  
    76.     //-----Need Add Remove the Entity First  START---------  
    77.     NSManagedObject *exsitManagedObject=[self getManagedObject:mtlModel  
    78.                                                          error:error];  
    79.     if (exsitManagedObject!=nil) {  
    80.         [self.managedObjectContext deleteObject:exsitManagedObject];  
    81.         [self.managedObjectContext save:error];  
    82.     };  
    83.     //-----Need Add Remove the Entity First  END-----------  
    84.       
    85.     NSManagedObject *managedObject = [MTLManagedObjectAdapter  
    86.                                       managedObjectFromModel:mtlModel  
    87.                                       insertingIntoContext:self.managedObjectContext  
    88.                                       error:error];  
    89.       
    90.     if (managedObject==nil) {  
    91.         NSLog(@"[NSManagedObject] Error:%@",*error);  
    92.         return NO;  
    93.     }  
    94.       
    95.     if (![self.managedObjectContext save:error]) {  
    96.         NSLog(@"[self.managedObjectContext] Error:%@",*error);  
    97.         return NO;  
    98.     };  
    99.     return YES;  
    100. };  
    101.   
    102. //从coredata中提取出MTLModel  
    103. -(MTLModel *)getMTLmodel:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
    104.                    error:(NSError *__autoreleasing *)error{  
    105.       
    106.     NSManagedObject *managedObject=[self getManagedObject:mtlModel error:error];  
    107.     MTLModel *mrlMotel=[[MTLModel alloc] init];  
    108.       
    109.     mrlMotel = [MTLManagedObjectAdapter modelOfClass:[mtlModel class]  
    110.                                    fromManagedObject:managedObject error:error];  
    111.       
    112.     if (error) {  
    113.         NSLog(@"[mrlMotel] Error:%@",*error);  
    114.     }  
    115.     return mrlMotel;  
    116. };  
    117.   
    118. //从coredata中获取已存的ManagedObject  
    119. -(NSManagedObject *)getManagedObject:(MTLModel<MTLManagedObjectSerializing> *)mtlModel  
    120.                                error:(NSError *__autoreleasing *)error{  
    121.     NSString *entityName=[[mtlModel class] managedObjectEntityName];  
    122.       
    123.     //获取entity中对象数量  
    124.     NSFetchRequest *requestCount=[NSFetchRequest fetchRequestWithEntityName:entityName];  
    125.     NSUInteger count=[self.managedObjectContext countForFetchRequest:requestCount  
    126.                                                                error:error];  
    127.     NSLog(@"count result:%d",count);  
    128.     NSLog(@"sortDescriptor result:%@",[[mtlModel class] sortDescriptor]);  
    129.       
    130.     //获取entity中第一个对象.这个对象必须存在且唯一。  
    131.     if (count==1) {  
    132.         NSFetchRequest *request=[[NSFetchRequest alloc] init];  
    133.         [request setEntity:[NSEntityDescription entityForName:entityName  
    134.                                        inManagedObjectContext:self.managedObjectContext]];  
    135.         NSSortDescriptor *sort=[[mtlModel class] sortDescriptor];  
    136.         NSArray *sortDes=[[NSArray alloc] initWithObjects:sort, nil nil];  
    137.         [request setSortDescriptors:sortDes];  
    138.         NSArray *getObject=[self.managedObjectContext  
    139.                             executeFetchRequest:request  
    140.                             error:error];  
    141.           
    142.         return [getObject objectAtIndex:0];  
    143.     }  
    144.     return nil;  
    145. }  
    146.   
    147. //从文件系统中删除sqlite文件  
    148. -(bool)deleteAllEntities{  
    149.     bool status=NO;  
    150.     NSError *error;  
    151.     @try{  
    152.         [[NSFileManager defaultManager] removeItemAtPath:[self storeURL].path  
    153.                                                    error:&error];  
    154.         status=YES;  
    155.     }  
    156.     @catch (NSException *exception) {  
    157.         status=NO;  
    158.     }  
    159.     @finally {  
    160.         return status;  
    161.     }  
    162. }  
    163.   
    164. @end  


    3.后台运行程序

    1. - (void)loadBannerList:(void (^)(NSArray *bannerList, NSError *error))block {  
    2.       
    3.     NSParameterAssert(block);  
    4.       
    5.     [self POST:@"webresources/homePage"  
    6.             parameters:nil  
    7.             resultClass:BannerWrapper.class  
    8.             resultKeyPath:nil  
    9.             completion:^(AFHTTPRequestOperation *operation, id responseObject, NSError *error) {  
    10.           
    11.         //-----------------------Persistence DEMO---------------------  
    12.         //If network error, get data from CoreData, else save data into CoreData  
    13.         if (!error) {  
    14.             NSError *err;  
    15.             Persistence *persistence=[[Persistence alloc] init];  
    16.             BOOL save=[persistence saveMTLModel:responseObject error:&err];  
    17.             if (save==NO) {  
    18.                 NSLog(@"Save ERROR!");  
    19.             }  
    20.         }else{  
    21.             NSError *err;  
    22.             Persistence *persistence=[[Persistence alloc] init];  
    23.             BannerWrapper *resObject=[[BannerWrapper alloc] init];  
    24.             BannerWrapper *object=[[BannerWrapper alloc] init];  
    25.             object=[persistence getMTLmodel:resObject error:&err];  
    26.   
    27.             responseObject=object;  
    28.               
    29.             //这个地方异常的奇怪,从coredata中应该返回打Array类型变成了set类型,所以这里临时作了一个转换。  
    30.             if ([object.bannerList isKindOfClass:[NSSet class]]) {  
    31.                 NSArray *objectArray = [(NSSet *)object.bannerList  allObjects];  
    32.                 ((BannerWrapper *)responseObject).bannerList=objectArray;  
    33.             }  
    34.         }  
    35.         //-----------------------------------------------------------  
    36.           
    37.         BannerWrapper *wrapper = responseObject;  
    38.         block(wrapper.bannerList, error);  
    39.           
    40.     }];  
    41. }  
  • 相关阅读:
    206. 反转链表
    JAVA 排序总结
    Codeforces Round #674 (Div. 3)
    【BM模板】
    【 lca 】最近公共祖先
    【 欧拉函数 】GCD
    【 裴蜀定理 】Border
    【调和级数 && 欧拉常数】 Harmonic Number
    【Lucas定理】组合数取模算法
    【 最短路 && 思维 】Escape Plan
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10746234.html
  • Copyright © 2020-2023  润新知