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.
// The name of the Core Data entity that the receiver serializes to and
// deserializes from.
// Specifies how to map property keys to different keys on the receiver's
// +managedObjectEntity.
.h 文件
#import
@interface BannerWrapper : MTLModel
@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
@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主要元素简要介绍
网上有很多图,但,还是觉得一本书上的这个图最好:
.h文件
#import
@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 *)mtlModel
error:(NSError * __autoreleasing *)error;
//从coredata中提取出MTLModel
-(MTLModel *)getMTLmodel:(MTLModel *)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 *)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 *)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 *)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];
[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
- (void)loadBannerList:(void (^)(NSArray *bannerList, NSError *error))block {
NSParameterAssert(block);
[self POST:@"webresources/homePage"
parameters:nil
resultClass:BannerWrapper.class
resultKeyPath:nil
completion:^(AFHTTPRequestOperation *operation, id responseObject, NSError *error) {
//-----------------------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);
}];
}