Skip to content

Instantly share code, notes, and snippets.

@sjgroomi
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save sjgroomi/09be2e908ed569ed25da to your computer and use it in GitHub Desktop.

Select an option

Save sjgroomi/09be2e908ed569ed25da to your computer and use it in GitHub Desktop.
An Objective-C port of my swift 2.0 core data stack(https://gist.github.com/sjgroomi/dcb3fbd11cc09686e685) which was based on Marcus Zarra's example (http://martiancraft.com/blog/2015/03/core-data-stack/)
//
// SGCoreDataStore.h
// Core Data Example
//
// Created by Groom, Stephen on 10/07/2015.
// Copyright © 2015 Stephen Groom. All rights reserved.
//
@import CoreData;
extern __nonnull NSString *const SGCoreDataStoreErrorDomain;
typedef NS_ENUM(NSUInteger, SGCoreDataStoreError)
{
SGCoreDataStoreErrorInvalidModelURL
};
@interface SGCoreDataStore : NSObject
/**
* For reading on the main thread only
*/
@property (nonatomic, strong, nonnull) NSManagedObjectContext *mainContext;
/**
* For all write operations and fetches which can be performed asynchronously
*/
@property (nonatomic, strong, nonnull) NSManagedObjectContext *backgroundContext;
/**
* Attempts to create and return a Core Data Store
*
* @param modelURL The URL of the .mom or .momd file
* @param storeURL The URL used to create or read the SQLite store
* @param error Will be populated with an underlying error if the store fails to initalize
*
* @return A SGCoreDataStore instance
*/
- (nullable instancetype)initWithModelURL:(nonnull NSURL *)modelURL
storeURL:(nonnull NSURL *)storeURL
error:(NSError **)error;
/**
* Saves changes to all managed object contexts in the logical correct order
*
* @param error A NSError** which is populated if there is an error at any point during the save process
*
* @warning This method is thread save but blocks until save operations have completed so avoid calling on the main thread
*/
- (void)save:(NSError **)error;
@end
//
// SGCoreDataStore.m
// Core Data Example
//
// Created by Groom, Stephen on 10/07/2015.
// Copyright © 2015 Stephen Groom. All rights reserved.
//
#import "SGCoreDataStore.h"
NSString *const SGCoreDataStoreErrorDomain = @"SGCoreDataStoreErrorDomain";
@interface SGCoreDataStore ()
@property (nonatomic, strong) NSManagedObjectContext *privateContext;
@end
@implementation SGCoreDataStore
- (nullable instancetype)initWithModelURL:(nonnull NSURL *)modelURL
storeURL:(nonnull NSURL *)storeURL
error:(NSError **)error
{
NSManagedObjectModel *objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
if (!objectModel)
{
if (error != NULL)
{
*error = [NSError errorWithDomain:SGCoreDataStoreErrorDomain code:SGCoreDataStoreErrorInvalidModelURL userInfo:nil];
}
return nil;
}
NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:@{NSInferMappingModelAutomaticallyOption : @(YES),
NSMigratePersistentStoresAutomaticallyOption : @(YES)}
error:error])
{
return nil;
}
self = [super init];
if (self)
{
_privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_privateContext.persistentStoreCoordinator = persistentStoreCoordinator;
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainContext.parentContext = _privateContext;
_backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_backgroundContext.parentContext = _mainContext;
}
return self;
}
- (void)save:(NSError **)error
{
__block NSError *localError = nil;
__weak typeof(self) weakSelf = self;
[self.backgroundContext performBlockAndWait:^{
[weakSelf.backgroundContext save:&localError];
}];
if (!localError)
{
[self.mainContext performBlockAndWait:^{
[weakSelf.mainContext save:&localError];
}];
}
if (!localError)
{
[self.privateContext performBlockAndWait:^{
[weakSelf.privateContext save:&localError];
}];
}
if (error)
{
*error = localError;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment