Skip to content

Instantly share code, notes, and snippets.

@philosopherdog
Last active April 14, 2016 16:05
Show Gist options
  • Save philosopherdog/4219a1b8f446acf8c8dc to your computer and use it in GitHub Desktop.
Save philosopherdog/4219a1b8f446acf8c8dc to your computer and use it in GitHub Desktop.
Core Data Moved To External Files in Objective-C
#import <Foundation/Foundation.h>
@import CoreData;
@interface SATCoreData : NSObject
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@property (nonatomic) NSString *nameOfPersistentStore; // required
@end
#import "SATCoreData.h"
@interface SATCoreData()
@end
@implementation SATCoreData
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.cocoanutmobile.EveryDoCoreData" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSAssert(self.nameOfPersistentStore, @"Setting nameOfPersistentStore required!");
NSString *pathComponent = [self.nameOfPersistentStore stringByAppendingString:@".sqlite"];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:pathComponent];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
// get app name
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:self.nameOfPersistentStore withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
// Use this if you want to use the appName as the name of the Persistent Store
//- (NSString *)appName {
// return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
//}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
@end
@philosopherdog
Copy link
Author

Simply add these two files to your project. Create a Data Model object in xCode and give it the same name as the name you pass to the nameOfPersistentStore property. Import the SATCoreData.h into your App Delegate, and instantiate it there. Pass the class to your root view controller. Alternatively, you can create a Model manager, instantiate it from the App Delegate and get it to handle instantiating SATCoreData. You only want one SATCoreData instance kicking around. So, kick it off from the App Delegate and pass the instance or it's manager to your root view controller. If you're lazy you can expose a property to your instance of the core data stack in the App Delegate that way you can access it from anywhere in your app by getting a reference to the App Delegate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment