首页 > 代码库 > iOS 网络请求Json自动转存到CoreData(一)
iOS 网络请求Json自动转存到CoreData(一)
奉上地址一枚:GitHub 并自带demo~
项目需求:从网络获取Json后,将Json自动转存到CoreData中。
本次任务:对CoreData封装,完成基本的增删改查,多线程操作。
我们总是在跌跌撞撞中,不断成长。
CoreDataActivity.h
// // CoreDataActivity.h // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import <Foundation/Foundation.h> #import "DEBUG.h" #import "NSFetchRequest+helper.h" #import "NSManagedObject+helper.h" #import "NSManagedObjectModel+helper.h" #import "NSPersistentStoreCoordinator+helper.h" @import CoreData; @interface CoreDataActivity : NSObject // Parent Context @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; // Child Context @property (strong, nonatomic) NSManagedObjectContext *childManagedObjectContext; @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; + (CoreDataActivity *)shareInstance; - (NSManagedObjectContext *)createChildManagedObjectContext; - (void)saveContext; - (void)deleteWithEntity:(NSString *)entityName attributeName:(NSString *)attributeName value:(id)value; - (void)updateWithEntity:(NSString *)entityName attributeName:(NSString *)attributeName oldValue:(id)oldValue newValue:(id)newValue; - (NSArray *)attributeForEntity:(NSString *)entityName; - (NSArray *)attributeForEntity:(NSString *)entityName sortByAttributeName:(NSString *)sortDescriptorName; @end
CoreDataActivity.m
// // CoreDataActivity.m // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // // References: // http://cutecoder.org/featured/asynchronous-core-data-document/ // http://www.touchwonders.com/fast-and-non-blocking-core-data-back-end-programming/ #import "CoreDataActivity.h" #warning mark - Change your CoreDataFileName #define CoreDataFileName @"QGLCoreDataPlugin" static CoreDataActivity *coreDataActivity = nil; @implementation CoreDataActivity #pragma mark - SingleInstance + (CoreDataActivity *)shareInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ coreDataActivity = [[CoreDataActivity alloc] init]; [coreDataActivity initCoreData]; }); return coreDataActivity; } #pragma mark - Init for CoreData - (void)initCoreData { NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator) { _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; _childManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_childManagedObjectContext setParentContext:_managedObjectContext]; } } #pragma mark - Creating the parent context // Just create your // NSManagedObjectModel // and // NSPersistentStoreCoordinator // as before // Initialize the parent // NSManagedObjectContext // by setting its concurrency type to // NSMainQueueConcurrencyType //Set the persistentStoreCoordinator of the newly created context - (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; } - (NSManagedObjectModel *)managedObjectModel { NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSManagedObjectModel URLForManagedObjectModelName:CoreDataFileName]]; return model; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSURL *storeURL = [NSPersistentStoreCoordinator URLForNSPersistentStoreCoordinatorName:CoreDataFileName]; NSError *error = nil; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { DLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return persistentStoreCoordinator; } #pragma mark - Creating the child context // Create a new // NSManagedObjectContext // with concurrency type // NSPrivateQueueConcurrencyType // Set its parentContext (setParentContext:) to the above created // NSManagedObjectContext - (NSManagedObjectContext *)childManagedObjectContext { if (_childManagedObjectContext) { return _childManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator) { _childManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_childManagedObjectContext setPersistentStoreCoordinator:coordinator]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(childMergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:_childManagedObjectContext]; } return _childManagedObjectContext; } - (void)childMergeChangesFromContextDidSaveNotification:(NSNotification *)notification { DLog(@"ChildContext did save."); [self performSelectorOnMainThread:@selector(mainMergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; } - (void)mainMergeChangesFromContextDidSaveNotification:(NSNotification *)notification { [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification]; } - (NSManagedObjectContext *)createChildManagedObjectContext { NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [context setParentContext:_managedObjectContext]; return context; } #pragma mark -SaveContext //MARK:Consider about synchronous or asynchronous /* When you cannot guarantee to conform to thread confinement (or you just want to be sure). One can pass a block which does some heavy work using the desired managedObjectContext and Core Data will automatically schedule the block for execution and uses the correct thread. Depending on which function is called the operation will be synchronous ( performBlockAndWait: ) or asynchronous ( performBlock: ). */ - (void)saveContext { //TODO:First sava childManagedObjectContext and then save the main Quene‘s managedObjectContext. // NSError *error = nil; // if ([_managedObjectContext hasChanges] && ![_managedObjectContext save:&error]) { // ELog(error); // abort(); // } //BETTER:It‘s better using performBlock rather than performBlockAndWait.Or you will wait for the block to be performed. [self.childManagedObjectContext performBlock:^{ NSError *error = nil; [self.childManagedObjectContext save:&error]; [self.managedObjectContext performBlock:^{ NSError *parentError = nil; [self.managedObjectContext save:&parentError]; }]; }]; } /* ======================================================================================================================== Things to remember: After creating or modifying a NSManagedObject save to its managedObjectContext to keep everything in sync! Objects created in one managedObjectContext cannot be used in another managedObjectContext without triggering an exception. Always convert them to the managedObjectContext you want to use them in. Check out the github link down below for some sample code. ======================================================================================================================== */ // Normal Operation - (void)deleteWithEntity:(NSString *)entityName attributeName:(NSString *)attributeName value:(id)value { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", attributeName, value]; NSFetchRequest *fetchRequst = [NSFetchRequest fetchRequestWithManagedObjectContext:self.managedObjectContext EntityName:entityName SortByAttributeName:attributeName Predicate:predicate]; NSError *error = nil; NSArray *resultArray = [self.managedObjectContext executeFetchRequest:fetchRequst error:&error]; if (error) { ELog(error); } if ([resultArray count]) { for (id obj in resultArray) { [self.managedObjectContext deleteObject:obj]; } } [self saveContext]; } - (void)updateWithEntity:(NSString *)entityName attributeName:(NSString *)attributeName oldValue:(id)oldValue newValue:(id)newValue { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", attributeName, oldValue]; NSFetchRequest *fetchRequst = [NSFetchRequest fetchRequestWithManagedObjectContext:self.managedObjectContext EntityName:entityName SortByAttributeName:attributeName Predicate:predicate]; NSError *error = nil; NSArray *resultArray = [self.managedObjectContext executeFetchRequest:fetchRequst error:&error]; if (error) { ELog(error); } if ([resultArray count]) { for (int i = 0; i < [resultArray count]; i ++) { [[resultArray objectAtIndex:i] setValue:newValue forKey:attributeName]; } } [self saveContext]; } - (NSArray *)attributeForEntity:(NSString *)entityName { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName]; return [self.managedObjectContext executeFetchRequest:fetchRequest error:nil]; } - (NSArray *)attributeForEntity:(NSString *)entityName sortByAttributeName:(NSString *)sortDescriptorName { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:self.managedObjectContext EntityName:entityName SortDescriptorName:sortDescriptorName]; return [self.managedObjectContext executeFetchRequest:fetchRequest error:nil]; } @end
对NSFetchRequest扩展:
NSFetchRequest+helper.h
// // NSFetchRequest+helper.h // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-17. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import <Foundation/Foundation.h> @import CoreData; @interface NSFetchRequest (helper) //TODO: + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortDescriptorName:(NSString *)sortDescriptorName; //TODO:Using NSPredicate + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Limit:(NSInteger)limit; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset Limit:(NSInteger)limit; //TODO:Using NSPredicate and SortDescriptorName + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Limit:(NSInteger)limit; + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset Limit:(NSInteger)limit; @end
NSFetchRequest+helper.m
// // NSFetchRequest+helper.m // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-17. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import "NSFetchRequest+helper.h" @implementation NSFetchRequest (helper) + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName { NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:contect]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:entity]; [fetchRequest setReturnsObjectsAsFaults:NO]; return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortDescriptorName:(NSString *)sortDescriptorName { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName]; if (sortDescriptorName && ![sortDescriptorName isEqualToString:@""]) { NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortDescriptorName ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName]; [fetchRequest setPredicate:predicate]; return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName Predicate:predicate]; if (offset > 0) { [fetchRequest setFetchOffset:offset]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Limit:(NSInteger)limit { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName Predicate:predicate]; if (limit > 0) { [fetchRequest setFetchLimit:limit]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset Limit:(NSInteger)limit { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName Predicate:predicate]; if (offset > 0) { [fetchRequest setFetchOffset:offset]; } if (limit > 0) { [fetchRequest setFetchLimit:limit]; } return fetchRequest; } //TODO:Using NSPredicate and SortDescriptorName + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName Predicate:predicate]; if (sortDescriptorName && ![sortDescriptorName isEqualToString:@""]) { NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortDescriptorName ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName SortByAttributeName:sortDescriptorName Predicate:predicate]; if (offset > 0) { [fetchRequest setFetchOffset:offset]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Limit:(NSInteger)limit { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName SortByAttributeName:sortDescriptorName Predicate:predicate]; if (limit > 0) { [fetchRequest setFetchLimit:limit]; } return fetchRequest; } + (NSFetchRequest *)fetchRequestWithManagedObjectContext:(NSManagedObjectContext *)contect EntityName:(NSString *)entityName SortByAttributeName:(NSString *)sortDescriptorName Predicate:(NSPredicate *)predicate Offset:(NSInteger)offset Limit:(NSInteger)limit { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithManagedObjectContext:contect EntityName:entityName SortByAttributeName:sortDescriptorName Predicate:predicate]; if (offset > 0) { [fetchRequest setFetchOffset:offset]; } if (limit > 0) { [fetchRequest setFetchLimit:limit]; } return fetchRequest; } @end
对NSManagedObject的扩展:
NSManagedObject+helper.h
// // NSManagedObject+helper.h // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import <Foundation/Foundation.h> @import CoreData; @interface NSManagedObject (helper) + (id)createNSManagedObjectForName:(NSString *)name; + (void)deleteNSManagedObject:(id)object; @end
// // NSManagedObject+helper.m // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import "NSManagedObject+helper.h" #import "CoreDataActivity.h" @implementation NSManagedObject (helper) + (id)createNSManagedObjectForName:(NSString *)name { //TODO:To judge whether the Main Thread. This is importmeng! CoreDataActivity *coreDateActivity = [CoreDataActivity shareInstance]; NSManagedObjectContext *context = [NSThread mainThread] ? coreDateActivity.managedObjectContext : coreDateActivity.childManagedObjectContext; return [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context]; } + (void)deleteNSManagedObject:(id)object { [[CoreDataActivity shareInstance].managedObjectContext deleteObject:object]; } @end
对NSManagedObjectModel的扩展:
NSManagedObjectModel+helper.h
// // NSManagedObjectModel+helper.h // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import <Foundation/Foundation.h> @import CoreData; @interface NSManagedObjectModel (helper) + (NSURL *)URLForManagedObjectModelName:(NSString *)modelName; //+ (NSManagedObjectModel *)URLForMananagedObjectModel:(NSString *)urlStr; @end
// // NSManagedObjectModel+helper.m // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import "NSManagedObjectModel+helper.h" @implementation NSManagedObjectModel (helper) + (NSURL *)URLForManagedObjectModelName:(NSString *)modelName { NSURL *modelUrl = [[NSBundle mainBundle] URLForResource:modelName withExtension:@"momd"]; return modelUrl; } //+ (NSManagedObjectModel *)URLForMananagedObjectModel:(NSString *)urlStr { // NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSManagedObjectModel URLForManagedObjectModelName:urlStr]]; // return model; //} @end
对NSPersistentStoreCoordinator的扩展:
NSPersistentStoreCoordinator+helper.h
// // NSPersistentStoreCoordinator+helper.h // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import <Foundation/Foundation.h> @import CoreData; @interface NSPersistentStoreCoordinator (helper) + (NSURL *)URLForNSPersistentStoreCoordinatorName:(NSString *)fileName; @end
// // NSPersistentStoreCoordinator+helper.m // QGLCoreDataPlugin // // Created by Guicai.Li on 14-10-16. // Copyright (c) 2014年 Guicai Li. All rights reserved. // #import "NSPersistentStoreCoordinator+helper.h" @implementation NSPersistentStoreCoordinator (helper) + (NSURL *)URLForNSPersistentStoreCoordinatorName:(NSString *)fileName { NSString *dbFileName = [NSString stringWithFormat:@"%@.sqlite", fileName]; return [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:dbFileName]; } @end
iOS 网络请求Json自动转存到CoreData(一)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。