Core Data is Apple's framework for persisting data on Mac & iOS. It can be though of as an ORM, however it's probably a lot different than most ORMs you've used in the past. In this episode, we'll set up Core Data from scratch so you can see all the moving parts.
Links Episode Sample Code Core Data Book - Marcus Zarra - This is considered the best reference on Core Data out there. iOS Recipes - The data model technique I used in the episode came from this book. Highly recommended! Mogenerator - This tool generates classes based on your data model. I barely scratched the surface of this tool in the screencast, but this is widely used and could be considered standard practice. Be aware, though, that Xmo'd doesn't yet work in Xcode 4, so you'll have to use the script directly. Core Data Programming Guide - Apple's official documentation Setting up Core Data // BeersDataModel.h #import <CoreData/CoreData.h> @interface BeersDataModel : NSObject + (id)sharedDataModel; @property (nonatomic, readonly) NSManagedObjectContext *mainContext; @property (nonatomic, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (NSString *)modelName; - (NSString *)pathToModel; - (NSString *)storeFilename; - (NSString *)pathToLocalStore; @end // BeersDataModel.m #import "BeersDataModel.h" @interface BeersDataModel () @property (nonatomic, strong) NSManagedObjectModel *managedObjectModel; - (NSString *)documentsDirectory; @end @implementation BeersDataModel @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; @synthesize mainContext = _mainContext; + (id)sharedDataModel { static BeersDataModel *__instance = nil; if (__instance == nil) { __instance = [[BeersDataModel alloc] init]; } return __instance; } - (NSString *)modelName { return @"Beers"; } - (NSString *)pathToModel { return [[NSBundle mainBundle] pathForResource:[self modelName] ofType:@"momd"]; } - (NSString *)storeFilename { return [[self modelName] stringByAppendingPathExtension:@"sqlite"]; } - (NSString *)pathToLocalStore { return [[self documentsDirectory] stringByAppendingPathComponent:[self storeFilename]]; } - (NSString *)documentsDirectory { NSString *documentsDirectory = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); documentsDirectory = [paths objectAtIndex:0]; return documentsDirectory; } - (NSManagedObjectContext *)mainContext { if (_mainContext == nil) { _mainContext = [[NSManagedObjectContext alloc] init]; _mainContext.persistentStoreCoordinator = [self persistentStoreCoordinator]; } return _mainContext; } - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel == nil) { NSURL *storeURL = [NSURL fileURLWithPath:[self pathToModel]]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:storeURL]; } return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator == nil) { NSLog(@"SQLITE STORE PATH: %@", [self pathToLocalStore]); NSURL *storeURL = [NSURL fileURLWithPath:[self pathToLocalStore]]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; NSError *e = nil; if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&e]) { NSDictionary *userInfo = [NSDictionary dictionaryWithObject:e forKey:NSUnderlyingErrorKey]; NSString *reason = @"Could not create persistent store."; NSException *exc = [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:userInfo]; @throw exc; } _persistentStoreCoordinator = psc; } return _persistentStoreCoordinator; } @end Generating the entities with Mogenerator mogenerator --template-var arc=true --model Beers.xcdatamodeld/Beers.xcdatamodel (Note in the video I had the --template-var setting after the model, and that's why the setting wasn't actually applied) Saving Data NSManagedObjectContext *context = [[BeersDataModel sharedDataModel] mainContext]; if (context) { NSLog(@"Context is ready!"); Beer *beer = [Beer insertInManagedObjectContext:context]; beer.name = @"90 Minute Imperial IPA"; Brewery *brewery = [Brewery insertInManagedObjectContext:context]; brewery.name = @"Dogfish Head"; beer.brewery = brewery; [context save:nil]; } else { NSLog(@"Context was nil :("); }