Created
November 19, 2012 03:12
-
-
Save troystribling/4108755 to your computer and use it in GitHub Desktop.
Simple Core Data wrapper. Supports background access.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "NSManagedObject+DataManager.h" | |
@interface DataManager : NSObject | |
@property (nonatomic, strong, readonly) NSManagedObjectModel* managedObjectModel; | |
@property (nonatomic, strong, readonly) NSManagedObjectContext* managedObjectContext; | |
@property (nonatomic, strong, readonly) NSPersistentStoreCoordinator* persistentStoreCoordinator; | |
@property (nonatomic, strong) NSURL* modelURL; | |
@property (nonatomic, strong) NSString* persistantStoreName; | |
@property(nonatomic, assign) dispatch_queue_t backgroundQueue; | |
+ (DataManager*)create; | |
+ (DataManager*)instance; | |
+ (void)waitForSavesToFinish; | |
- (NSManagedObjectContext*)createContext; | |
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification*)notification; | |
- (void)performInBackground:(void(^)(NSManagedObjectContext* contexr))operation; | |
- (BOOL)save; | |
- (BOOL)saveInContext:(NSManagedObjectContext*)_context; | |
- (BOOL)destroy:(NSManagedObject*)_object; | |
- (BOOL)destroy:(NSManagedObject*)_object inContext:(NSManagedObjectContext*)_context; | |
- (NSUInteger)count:(NSFetchRequest*)_fetchRequest; | |
- (NSUInteger)count:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context; | |
- (NSArray*)fetch:(NSFetchRequest*)_fetchRequest; | |
- (NSArray*)fetch:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context; | |
- (id)fetchFirst:(NSFetchRequest*)_fetchRequest; | |
- (id)fetchFirst:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context; | |
- (id)fetchWithID:(NSManagedObjectID*)objectID inContext:(NSManagedObjectContext*)context; | |
- (id)fetchWithID:(NSManagedObjectID*)objectID; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DataManager.h" | |
#import "UIAlertView+Extensions.h" | |
static DataManager* thisDataManager = nil; | |
@interface DataManager () | |
- (NSManagedObjectContext*)managedObjectContext; | |
- (NSManagedObjectModel*)managedObjectModel; | |
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator; | |
- (NSURL*)applicationDocumentsDirectory; | |
@end | |
@implementation DataManager | |
@synthesize managedObjectContext = __managedObjectContext; | |
@synthesize managedObjectModel = __managedObjectModel; | |
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator; | |
@synthesize modelURL, persistantStoreName; | |
#pragma mark - | |
#pragma mark DataContextManager | |
+ (DataManager*)create { | |
if (thisDataManager == nil) { | |
thisDataManager = [[self alloc] init]; | |
} | |
return thisDataManager; | |
} | |
+ (DataManager*)instance { | |
return thisDataManager; | |
} | |
+ (void)waitForSavesToFinish { | |
dispatch_sync([DataManager instance].backgroundQueue, ^{}); | |
} | |
- (id)init { | |
self = [super init]; | |
if (self) { | |
self.backgroundQueue = dispatch_queue_create("com.genmobapp.dataManager", NULL); | |
} | |
return self; | |
} | |
- (NSManagedObjectContext*)createContext { | |
NSManagedObjectContext* newMoc = [[NSManagedObjectContext alloc] init]; | |
[newMoc setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; | |
return newMoc; | |
} | |
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification*)notification { | |
[__managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; | |
[[NSNotificationCenter defaultCenter] removeObserver:self]; | |
} | |
- (void)performInBackground:(void(^)(NSManagedObjectContext* context))operation { | |
dispatch_async(self.backgroundQueue, ^{ | |
NSManagedObjectContext *backgroundContext = [self createContext]; | |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:backgroundContext]; | |
operation(backgroundContext); | |
}); | |
} | |
- (BOOL)save { | |
return [self saveInContext:__managedObjectContext]; | |
} | |
- (BOOL)saveInContext:(NSManagedObjectContext*)_context { | |
NSError *error = nil; | |
BOOL status = YES; | |
if (![_context save:&error]) { | |
status = NO; | |
} | |
return status; | |
} | |
- (BOOL)destroy:(NSManagedObject*)_object { | |
return [self destroy:_object inContext:__managedObjectContext]; | |
} | |
- (BOOL)destroy:(NSManagedObject*)_object inContext:(NSManagedObjectContext*)_context { | |
[_context deleteObject:_object]; | |
return [self saveInContext:_context]; | |
} | |
- (NSUInteger)count:(NSFetchRequest*)_fetchRequest { | |
return [self count:_fetchRequest inContext:__managedObjectContext]; | |
} | |
- (NSUInteger)count:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context { | |
NSError* error; | |
NSUInteger count = [_context countForFetchRequest:_fetchRequest error:&error]; | |
if (count == NSNotFound) { | |
[UIAlertView alertOnError:error]; | |
abort(); | |
} | |
return count; | |
} | |
- (NSArray*)fetch:(NSFetchRequest*)_fetchRequest { | |
return [self fetch:_fetchRequest inContext:__managedObjectContext]; | |
} | |
- (NSArray*)fetch:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context { | |
NSError* error; | |
NSArray* fetchResults = [_context executeFetchRequest:_fetchRequest error:&error]; | |
if (fetchResults == nil) { | |
[UIAlertView alertOnError:error]; | |
abort(); | |
} | |
return fetchResults; | |
} | |
- (id)fetchFirst:(NSFetchRequest*)_fetchRequest { | |
return [self fetchFirst:_fetchRequest inContext:__managedObjectContext]; | |
} | |
- (id)fetchFirst:(NSFetchRequest*)_fetchRequest inContext:(NSManagedObjectContext*)_context { | |
id fetchResult = nil; | |
_fetchRequest.fetchLimit = 1; | |
NSArray* fetchResults = [self fetch:_fetchRequest inContext:_context]; | |
if ([fetchResults count] > 0) { | |
fetchResult = [fetchResults objectAtIndex:0]; | |
} | |
return fetchResult; | |
} | |
- (id)fetchWithID:(NSManagedObjectID*)objectID inContext:(NSManagedObjectContext*)context { | |
NSError* error = nil; | |
NSManagedObject *fetchResult = [context existingObjectWithID:objectID error:&error]; | |
if (error) { | |
[UIAlertView alertOnError:error]; | |
abort(); | |
} | |
return fetchResult; | |
} | |
- (id)fetchWithID:(NSManagedObjectID*)objectID { | |
return [self fetchWithID:objectID inContext:__managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark DataContextManager PrivateAPI | |
- (NSManagedObjectContext*)managedObjectContext { | |
if (__managedObjectContext != nil) { | |
return __managedObjectContext; | |
} | |
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; | |
if (coordinator != nil) { | |
__managedObjectContext = [[NSManagedObjectContext alloc] init]; | |
[__managedObjectContext setPersistentStoreCoordinator:coordinator]; | |
} | |
return __managedObjectContext; | |
} | |
- (NSManagedObjectModel*)managedObjectModel { | |
if (__managedObjectModel != nil) { | |
return __managedObjectModel; | |
} | |
NSLog(@"%@", [NSBundle mainBundle]); | |
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL]; | |
return __managedObjectModel; | |
} | |
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator { | |
if (__persistentStoreCoordinator != nil) { | |
return __persistentStoreCoordinator; | |
} | |
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:self.persistantStoreName]; | |
NSError *error = nil; | |
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; | |
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { | |
NSLog(@"Unresolved error %@, %@", error, [error userInfo]); | |
abort(); | |
} | |
return __persistentStoreCoordinator; | |
} | |
- (NSURL*)applicationDocumentsDirectory { | |
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <CoreData/CoreData.h> | |
@interface NSManagedObject (DataManager) | |
+ (NSEntityDescription*)entityInContext:(NSManagedObjectContext*)context; | |
+ (NSFetchRequest*)fetchRequestInContext:(NSManagedObjectContext*)context; | |
+ (NSArray*)findAllInContext:(NSManagedObjectContext*)context; | |
+ (NSArray*)findAll; | |
+ (NSArray*)findAllWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context; | |
+ (NSArray*)findAllWithPredicate:(NSPredicate*)predicate; | |
+ (NSArray*)findAllWithSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context; | |
+ (NSArray*)findAllWithSortDescriptors:(NSArray*)sortDescriptors; | |
+ (NSArray*)findAllWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context; | |
+ (NSArray*)findAllWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors; | |
+ (id)findFirstInContext:(NSManagedObjectContext*)context; | |
+ (id)findFirst; | |
+ (id)findFirstWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context; | |
+ (id)findFirstWithPredicate:(NSPredicate*)predicate; | |
+ (id)findFirstWithSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context; | |
+ (id)findFirstWithSortDescriptors:(NSArray*)sortDescriptors; | |
+ (id)findFirstWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context; | |
+ (id)findFirstWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors; | |
+ (id)findWithID:(NSManagedObjectID*)objectID inContext:(NSManagedObjectContext*)context; | |
+ (id)findWithID:(NSManagedObjectID*)objectID; | |
+ (NSInteger)countInContext:(NSManagedObjectContext*)context; | |
+ (NSInteger)count; | |
+ (NSInteger)countWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context; | |
+ (NSInteger)countWithPredicate:(NSPredicate*)predicate; | |
+ (BOOL)existsInContext:(NSManagedObjectContext*)context; | |
+ (BOOL)exists; | |
+ (BOOL)existsWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context; | |
+ (BOOL)existsWithPredicate:(NSPredicate*)predicate; | |
+ (id)createInContext:(NSManagedObjectContext*)context; | |
+ (id)create; | |
- (BOOL)save; | |
- (BOOL)destroy; | |
- (void)discard; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DataManager.h" | |
#import "NSObject+Extensions.h" | |
#import "NSManagedObject+DataManager.h" | |
@interface NSManagedObject (DataManagerPrivateAPI) | |
@end | |
@implementation NSManagedObject (DataManager) | |
#pragma mark - | |
#pragma Fetch Request | |
+ (NSEntityDescription*)entityInContext:(NSManagedObjectContext*)context { | |
return [NSEntityDescription entityForName:[self className] inManagedObjectContext:context]; | |
} | |
+ (NSFetchRequest*)fetchRequestInContext:(NSManagedObjectContext*)context { | |
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; | |
NSEntityDescription* entity = [self entityInContext:context]; | |
[fetchRequest setEntity:entity]; | |
return fetchRequest; | |
} | |
#pragma mark - | |
#pragma mark findAll | |
+ (NSArray*)findAllInContext:(NSManagedObjectContext*)context { | |
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]; | |
return [self findAllWithPredicate:nil andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (NSArray*)findAll { | |
return [self findAllInContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (NSArray*)findAllWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context { | |
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]; | |
return [self findAllWithPredicate:predicate andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (NSArray*)findAllWithPredicate:(NSPredicate*)predicate { | |
return [self findAllWithPredicate:predicate inContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (NSArray*)findAllWithSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context { | |
return [self findAllWithPredicate:nil andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (NSArray*)findAllWithSortDescriptors:(NSArray*)sortDescriptors { | |
return [self findAllWithSortDescriptors:sortDescriptors inContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (NSArray*)findAllWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context { | |
NSFetchRequest *fetchRequest = [self fetchRequestInContext:context]; | |
[fetchRequest setPredicate:predicate]; | |
[fetchRequest setSortDescriptors:sortDescriptors]; | |
return [[DataManager instance] fetch:fetchRequest inContext:context]; | |
} | |
+ (NSArray*)findAllWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors { | |
return [self findAllWithPredicate:predicate andSortDescriptors:sortDescriptors inContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark findFirst | |
+ (id)findFirstInContext:(NSManagedObjectContext*)context { | |
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]; | |
return [self findFirstWithPredicate:nil andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (id)findFirst { | |
return [self findFirstInContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (id)findFirstWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context { | |
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]; | |
return [self findFirstWithPredicate:predicate andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (id)findFirstWithPredicate:(NSPredicate*)predicate { | |
return [self findFirstWithPredicate:predicate inContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (id)findFirstWithSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context { | |
return [self findFirstWithPredicate:nil andSortDescriptors:sortDescriptors inContext:context]; | |
} | |
+ (id)findFirstWithSortDescriptors:(NSArray*)sortDescriptors { | |
return [self findFirstWithSortDescriptors:sortDescriptors inContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (id)findFirstWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors inContext:(NSManagedObjectContext*)context { | |
NSFetchRequest *fetchRequest = [self fetchRequestInContext:context]; | |
[fetchRequest setPredicate:predicate]; | |
[fetchRequest setSortDescriptors:sortDescriptors]; | |
return [[DataManager instance] fetchFirst:fetchRequest inContext:context]; | |
} | |
+ (id)findFirstWithPredicate:(NSPredicate *)predicate andSortDescriptors:(NSArray*)sortDescriptors { | |
return [self findFirstWithPredicate:predicate andSortDescriptors:sortDescriptors inContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark fetchWithID | |
+ (id)findWithID:(NSManagedObjectID*)objectID inContext:(NSManagedObjectContext*)context { | |
return [[DataManager instance] fetchWithID:objectID inContext:context]; | |
} | |
+ (id)findWithID:(NSManagedObjectID*)objectID { | |
return [self findWithID:objectID inContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark count | |
+ (NSInteger)countInContext:(NSManagedObjectContext*)context { | |
return [self countWithPredicate:nil inContext:context]; | |
} | |
+ (NSInteger)count { | |
return [self countInContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (NSInteger)countWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context { | |
NSFetchRequest *fetchRequest = [self fetchRequestInContext:context]; | |
[fetchRequest setPredicate:predicate]; | |
return [[DataManager instance] count:fetchRequest inContext:context]; | |
} | |
+ (NSInteger)countWithPredicate:(NSPredicate*)predicate { | |
return [self countWithPredicate:predicate inContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark exists | |
+ (BOOL)existsInContext:(NSManagedObjectContext*)context { | |
return [self existsWithPredicate:nil inContext:context]; | |
} | |
+ (BOOL)exists { | |
return [self existsInContext:[DataManager instance].managedObjectContext]; | |
} | |
+ (BOOL)existsWithPredicate:(NSPredicate*)predicate inContext:(NSManagedObjectContext*)context { | |
NSInteger count = [self countWithPredicate:predicate inContext:context]; | |
if (count > 0) { | |
return YES; | |
} else { | |
return NO; | |
} | |
} | |
+ (BOOL)existsWithPredicate:(NSPredicate*)predicate { | |
return [self existsWithPredicate:predicate inContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark create | |
+ (id)createInContext:(NSManagedObjectContext*)context { | |
NSDate *now = [NSDate date]; | |
id model = [NSEntityDescription insertNewObjectForEntityForName:[self className] inManagedObjectContext:context]; | |
[model performSelector:@selector(setCreatedAt:) withObject:now]; | |
[model performSelector:@selector(setUpdatedAt:) withObject:now]; | |
return model; | |
} | |
+ (id)create { | |
return [self createInContext:[DataManager instance].managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark save | |
- (BOOL)save { | |
return [[DataManager instance] saveInContext:self.managedObjectContext]; | |
} | |
#pragma mark - | |
#pragma mark destroy | |
- (BOOL)destroy { | |
return [[DataManager instance] destroy:self inContext:self.managedObjectContext]; | |
} | |
- (void)discard { | |
[self.managedObjectContext reset]; | |
} | |
#pragma mark - | |
#pragma mark PrivateAPI | |
@end | |
@implementation NSManagedObject (DataManagerPrivateAPI) | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment