Skip to content

Instantly share code, notes, and snippets.

@troystribling
Created November 19, 2012 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save troystribling/4108755 to your computer and use it in GitHub Desktop.
Save troystribling/4108755 to your computer and use it in GitHub Desktop.
Simple Core Data wrapper. Supports background access.
#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
#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
#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
#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