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 文件
[objc] view
plaincopyprint?
-
#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文件
[objc] view
plaincopyprint?
-
#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文件
[objc] view
plaincopyprint?
-
#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文件
[objc] view
plaincopyprint?
-
#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 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.後台執行程序
[objc] view
plaincopyprint?
-
- (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);
-
-
}];
-
}