iOSDevCamp 2011 Core Data

4,875 views

Published on

a behind the scenes look at the core data objects added to your projects in xcode

Published in: Technology
  • Be the first to comment

iOSDevCamp 2011 Core Data

  1. 1. Pulling back the curtain on Core Data Chris Mar Spree Commerce http://cmar.me
  2. 2. Chris Mar• Spree Commerce• iOS and Rails Developer• @cmar• Grassy Knoll Apps - Redskins Radar
  3. 3. GoalPull back the curtain on Core Data so you will use it on your next project without fear!(we’ll focus on concepts, not a tutorial)
  4. 4. Core Data• Object Relational Mapping• Gives you access to a database without using sql or parsing results• Cocoa API with XCode tooling to assist you• Hibernate for Java, ActiveRecord for Rails
  5. 5. Storage Types• SQLite Database• XML• In-Memory we’ll focus on SQLite
  6. 6. NSManagedObject• Row from the database• Key-Value coding for fields• Optionally subclass• Fetched from NSManagedObjectContext [employee valueForKey:@"name"];
  7. 7. Managed Objects object1 object2 object1 object2 NSManagedObjectContext NSPersistentStoreCoordinator NSManagedObjectModel object1 SQLite Database
  8. 8. FetchRequest for NSManagedObjectsNSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:[NSEntityDescription entityForName:@"Order" inManagedObjectContext:self.managedObjectContext]];[request setPredicate:[NSPredicate predicateWithFormat:@"name like %@", @"*7*"]];NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];[request setSortDescriptors:sortDescriptors];self.orders = [self.managedObjectContext executeFetchRequest:request error:&error];[sortDescriptor release];[sortDescriptors release];[request release];
  9. 9. The Big 3 NSManagedObjectContextNSPersistentStoreCoordinator sqlite NSManagedObjectModel .xcdatamodel
  10. 10. NSManagedObjectContext• Object space for Managed Objects• Fetches from Persistent Store• Exclusive to a single thread• Commit and Discard Changes
  11. 11. NSManagedObjectContext (lazy loaded in AppDelegate)- (NSManagedObjectContext *)managedObjectContext{ if (__managedObjectContext != nil) { return __managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { __managedObjectContext = [[NSManagedObjectContext alloc] init]; [__managedObjectContext setPersistentStoreCoordinator:coordinator]; } return __managedObjectContext;}
  12. 12. NSPersistentStoreCoordinator• Manages connections to stores• Maps data model to database• Handles many stores• Shared between threads
  13. 13. NSPersistentStoreCoordinator (lazy loaded in AppDelegate)- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{ if (__persistentStoreCoordinator != nil) { return __persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite"]; NSError *error = nil; __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { } return __persistentStoreCoordinator; }
  14. 14. NSManagedObjectModel• Definition of database schema• Describes entity objects in store• Predefined Queries - Fetch Requests• Relationships between entities
  15. 15. NSManagedObjectModel (lazy loaded in AppDelegate)- (NSManagedObjectModel *)managedObjectModel{ if (__managedObjectModel != nil) { return __managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"]; __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return __managedObjectModel;}
  16. 16. NSManagedObjectModel XCode Editor
  17. 17. Insert new NSManagedObjectNSManagedObject *car = [NSEntityDescription insertNewObjectForEntityForName:@"Car” inManagedObjectContext:self.managedObjectContext];[car setValue:@"Jeep" forKey:@"name"];//Save the whole context which will save all the objects in itNSError *error = nil;if ([self.managedObjectContext save:&error]) { NSLog(@"Saved");} else { NSLog(@"Error saving %@", [error localizedDescription]);}
  18. 18. Threads Pass ID between threads Thread1 Thread2Object id=1 Object id=1 Object Object NSManagedObjectContext NSManagedObjectContext id=1 id=1 NSPersistentStoreCoordinator SQLite Database Object id=1
  19. 19. Memory Usageself.orders = [self.managedObjectContext executeFetchRequest:request error:&error]; • Load into an Array • All in memory • Updates • Fast and Easy for small tables
  20. 20. NSFetchedResultsController• Efficiently backs a UITableView• Reduces memory usage• Caches results• Updates table for changes
  21. 21. NSFetchedResultsControllerNSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsControlleralloc]initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContextsectionNameKeyPath:nil cacheName:@"Root"];
  22. 22. The Big Picture UITableView NSManagedObjectNSFetchedResultsController NSManagedObject iPhone NSManagedObject iPod touch NSManagedObject iPad NSManagedObject NSManagedObjectContext Steve Jobs RocksNSPersistentStoreCoordinator sqlite NSManagedObjectModel .xcdatamodel
  23. 23. Relationships• to-one • NSManagedObject *manager = [employee valueForKey:@”manager”];• to-many • NSSet *directReports = [manager valueForKey:@”directReports”];• Define inverses for data integrity• Delete Rules - nullify, cascade, deny
  24. 24. Fetched Properties• Lazy loaded query relationship• Sorted• Predicate - filtered• “Give a list of direct reports that begin with the letter C”
  25. 25. Fetch Requests• Uses NSPredicate for Where clause• Uses NSSortDescriptor for Order By clause• Can be saved with Managed Object Model [fetchRequestTemplateForName]
  26. 26. Predicates• [NSPredicate predicateWithFormat:@"name CONTAINS[c] %@", searchText];• @"name BETWEEN %@", [NSArray arrayWithObjects:@”a”,@”b”,nil]• MATCHES for regex• CONTAINS[c] for case insenstivity• AND, OR, NOT
  27. 27. Default Project with Core 1. [awakeFromNib] AppDelegate RootViewController set managedObjectContext 2. [managedObjectContext] 3. [cellForRowAtIndexPath] lazy load lazy load fetchedResultsController NSManagedObjectContext fetchedResultsController
  28. 28. SQLite Tables
  29. 29. Z_PRIMARYKEY
  30. 30. Preloaded Database• Load up database using Base• Base lets you import csv• Make sure you set the primary keys• On start check for existence, then copy it over
  31. 31. Preloading DatabaseNSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"products.sqlite"];NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; // Put down default db if it doesnt already existNSFileManager *fileManager = [NSFileManager defaultManager];if (![fileManager fileExistsAtPath:storePath]) { NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"preloaded_products" ofType:@"sqlite"]; if (defaultStorePath) { [fileManager copyItemAtPath:defaultStorePath toPath:storePatherror:NULL]; }}
  32. 32. FMDB• Objective-C wrapper for SQLite• Direct access• Low overhead• Great for simple data needs• https://github.com/ccgus/fmdb
  33. 33. FMDB ExampleFMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/my.db"];[db open]FMResultSet *rs = [db executeQuery:@"select * from orders where customer_id = ?",@"1000"];    [rs intForColumn:@"c"],    [rs stringForColumn:@"b"],    [rs dateForColumn:@"d"],    [rs doubleForColumn:@"e"]);}[rs close];[db close];
  34. 34. Links• http://www.raywenderlich.com/934/core-data- tutorial-getting-started• http://menial.co.uk/software/base/• https://github.com/ccgus/fmdb
  35. 35. Thank You! @cmar on twitter http://cmar.me

×