The document discusses Core Data, an object graph and persistence framework for managing and persisting data in iOS and macOS applications. It provides an overview of why and when to use Core Data, noting that it handles common tasks like data schema changes, syncing with servers and peers, undo/redo, threading, and notifying code of changes. It also discusses alternatives like MagicalRecord that simplify Core Data usage. The document recommends using Core Data for any non-trivial application where requirements may change over time, and provides code examples for common Core Data tasks like fetching, saving context, and queries.
6. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard.
7. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard. Really?
8. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard. Really? Really.
9. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard. Really? Really.
CoreData is hairy
10. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard. Really? Really.
CoreData is hairy
because it ...
11. Core Data?
-- It’s a big hairy mess!
YES! but Why?
Real problems are hard. Really? Really.
CoreData is hairy
because it ...
... solves real problems!
19. “Do you understand how to
structure real-world data
access for Mac and iOS
applications better than
Apple?”
20. “Do you understand how to
structure real-world data
access for Mac and iOS
applications better than
Apple?”
-- Nope.
21. • Handling future changes to the data
schema
• Bi-directional sync with servers
• Bi-directional sync with peers (e.g. iPad <-> iPhone)
• Undo - Redo
• Multithreading long-running operations
• Sync data between multiple threads
• Notifying faraway code about changes to
objects so that they can refresh or
update at appropriate intervals
Has your own so-called
“data stack” features like this?
23. But if...
I NEVER update my app!
My users NEVER do mistakes!
I NEVER use threads!
My app is just one view!
My data operations ARE all instantaneous!
Requirements of my apps NEVER changes!
37. •Programmer naivity
➜ “My app isn’t complex enought”
= I am too lazy to learn it
Why NOT to use Core Data?
38. •Programmer naivity
➜ “My app isn’t complex enought”
= I am too lazy to learn it
➜ “I dont like large frameworks - I used them
in HALF of my app and it was so much work!”
= Use entirely it or not. Otherwise it will
not save time & effort
Why NOT to use Core Data?
39. •Programmer naivity
➜ “My app isn’t complex enought”
= I am too lazy to learn it
➜ “I dont like large frameworks - I used them
in HALF of my app and it was so much work!”
= Use entirely it or not. Otherwise it will
not save time & effort
•Willful ignorance
Why NOT to use Core Data?
40. •Programmer naivity
➜ “My app isn’t complex enought”
= I am too lazy to learn it
➜ “I dont like large frameworks - I used them
in HALF of my app and it was so much work!”
= Use entirely it or not. Otherwise it will
not save time & effort
•Willful ignorance
➜ “I don’t have any idea what I’m talking
about, but it sounds like a bad idea to me”
= What?
Why NOT to use Core Data?
41. So?
Reading code is hard
Writing code is easy
Why learn when we can re-invent?
Really? If this works in your world,
Core Data is not for you...
42. OK, but when seriously NO?
Update HUGE part of DB in one
moment
Working with lots of records
➜ RSS Reader app
43. Still not ready to use Core Data?
Read this:
goo.gl/Flzrsk
Numbers here:
goo.gl/lNFjdr
52. // In the AppDelegate.h
@property (readonly, strong, nonatomic) NSManagedObjectContext
*managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator
*persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
// In the AppDelegate.m
- (void)applicationWillTerminate:(UIApplication *)application
{
// Saves changes in the application's managed object context before the application terminates.
[self saveContext];
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext
save:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the
application.
*/
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created from the application's model.
*/
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
{
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"blaba"
withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"blaba.sqlite"];
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;
}
#pragma mark - Application's Documents directory
/**
Returns the URL to the application's Documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
}
62. // In the AppDelegate.h
@property (readonly, strong, nonatomic) NSManagedObjectContext
*managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator
*persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
// In the AppDelegate.m
- (void)applicationWillTerminate:(UIApplication *)application
{
// Saves changes in the application's managed object context before the application terminates.
[self saveContext];
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext
save:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the
application.
*/
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created from the application's model.
*/
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
{
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"blaba"
withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"blaba.sqlite"];
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;
}
#pragma mark - Application's Documents directory
/**
Returns the URL to the application's Documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
}
CD
70. // Query to find all the persons store into the database
NSArray *persons = [Person MR_findAll];
// Query to find all the persons store into the database order by their
'firstname'
NSArray *personsSorted =
[Person MR_findAllSortedBy:@"firstname"
ascending:YES];
// Query to find all the persons store into the database which have 25
years old
NSArray *personsWhoHave22 =
[Person MR_findByAttribute:@"age"
withValue:[NSNumber numberWithInt:25]];
// Query to find the first person store into the databe
Person *person = [Person MR_findFirst];
MR
71. // Query to find all the persons store into the database
NSArray *persons = [Person MR_findAll];
// Query to find all the persons store into the database order by their
'firstname'
NSArray *personsSorted =
[Person MR_findAllSortedBy:@"firstname"
ascending:YES];
// Query to find all the persons store into the database which have 25
years old
NSArray *personsWhoHave22 =
[Person MR_findByAttribute:@"age"
withValue:[NSNumber numberWithInt:25]];
// Query to find the first person store into the databe
Person *person = [Person MR_findFirst];
MR
72. // Query to find all the persons store into the database
NSArray *persons = [Person findAll];
// Query to find all the persons store into the database order by their
'firstname'
NSArray *personsSorted =
[Person findAllSortedBy:@"firstname"
ascending:YES];
// Query to find all the persons store into the database which have 25
years old
NSArray *personsWhoHave22 =
[Person findByAttribute:@"age"
withValue:[NSNumber numberWithInt:25]];
// Query to find the first person store into the databe
Person *person = [Person findFirst];
MR
74. [MagicalRecord
saveWithBlock:^(NSManagedObjectContext
*localContext)
{
Post
*post
=
[Post
createInContext:localContext];
//
photo
processing
//
update
post
from
photo
processing
}
completion:^(BOOL
success,
NSError
*error)
{
//
This
is
called
when
data
done,
//
and
is
called
on
the
main
thread
}];
MR
79. But the docs sucks too!
It coves the basics, but I DO NEED to DIVE in!
goo.gl/9fNe0z
goo.gl/durEGR
80. Recap
•You want to use Core Data
•You want to use NSFetchResultsController
•You want to use MagicalRecord
•You want to use Mogenerator
•YOP, setup of that is epic!
•You want to use CocoaPods
•YOP, docs for CoreData and MagicalRecord
sucks
LET the CoreData work for you!