coredata - there is an orm you can like!

84
Tomáš Jukin @Inza Core Data there is an ORM you can like!

Upload: tomas-jukin

Post on 29-Aug-2014

416 views

Category:

Technology


0 download

DESCRIPTION

It doesn't hate you. CoreData is Cocoa for models! But it bites. I show you WHY and WHEN to use CoreData as well as HOW in order to prevent be biten by it. This slides were presented on my presentation at iCONdev at iCONprague 2014 on 23. 3. 2014 (more at http://www.iconprague.com/detailni-program/#core-data-i-orm-muzete-mit-radi)

TRANSCRIPT

Page 1: CoreData - there is an ORM you can like!

Tomáš Jukin@Inza

Core Datathere is an ORM you can like!

Page 2: CoreData - there is an ORM you can like!
Page 3: CoreData - there is an ORM you can like!

Core Data?

Page 4: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!

Page 5: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?

Page 6: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?Real problems are hard.

Page 7: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?Real problems are hard. Really?

Page 8: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?Real problems are hard. Really? Really.

Page 9: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?Real problems are hard. Really? Really.CoreData is hairy

Page 10: CoreData - there is an ORM you can like!

Core Data?

-- It’s a big hairy mess!YES! but Why?Real problems are hard. Really? Really.CoreData is hairy because it ...

Page 11: CoreData - there is an ORM you can like!

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!

Page 12: CoreData - there is an ORM you can like!

Tomáš Jukin@Inza

www.juicymo.cz@JuicymoCZ

Page 13: CoreData - there is an ORM you can like!

1) WHY and WHEN to use Core Data?

Page 14: CoreData - there is an ORM you can like!

1) WHY and WHEN to use Core Data?

2) HOW to use Core Data?

Page 15: CoreData - there is an ORM you can like!

WHY?

Page 16: CoreData - there is an ORM you can like!

1) Death

Page 17: CoreData - there is an ORM you can like!

1) Death2) Taxes

Page 18: CoreData - there is an ORM you can like!

1) Death2) Taxes

3) SW Requirements WILL change

Page 19: CoreData - there is an ORM you can like!

“Do you understand how to structure real-world data access for Mac and iOS applications better than

Apple?”

Page 20: CoreData - there is an ORM you can like!

“Do you understand how to structure real-world data access for Mac and iOS applications better than

Apple?”

-- Nope.

Page 21: CoreData - there is an ORM you can like!

• 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?

Page 22: CoreData - there is an ORM you can like!

Do I need these features?(= WHEN?)

Page 23: CoreData - there is an ORM you can like!

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!

Page 24: CoreData - there is an ORM you can like!

1) Death2) Taxes

3) SW Requirements WILL change

Page 25: CoreData - there is an ORM you can like!

... all of that is TRUE for you

Core Data is NOT for you.

Page 26: CoreData - there is an ORM you can like!

... all of that is TRUE for you

Core Data is NOT for you.

Otherwise you SHOULD use it.

Page 27: CoreData - there is an ORM you can like!

Core Data =

Do not implementDo not test

Do not optimize

Page 28: CoreData - there is an ORM you can like!

Core Data =

Do not implementDo not test

Do not optimizeData Stack code used by your app!

Apple has already done that!

Page 29: CoreData - there is an ORM you can like!

Fact

Apple’s high-level APIs can be much faster than YOUR “optimized” code at lower

levels

Page 30: CoreData - there is an ORM you can like!

Fact

Example:

Fast Image? ➜ UIImageView

Page 31: CoreData - there is an ORM you can like!

Fact

CoreData is

Cocoa for Models

Page 32: CoreData - there is an ORM you can like!

Cocoa for Models

Is UIButton easy?Is UITableView easy?

Is Delegation Pattern easy?Is InterfaceBuilder and

outlets easy?

Page 33: CoreData - there is an ORM you can like!

Cocoa for Models

Is UIButton easy?Is UITableView easy?

Is Delegation Pattern easy?Is InterfaceBuilder and

outlets easy?NOPE!

Page 34: CoreData - there is an ORM you can like!

Cocoa for Models

Are they powerful?

Page 35: CoreData - there is an ORM you can like!

Cocoa for Models

Are they powerful?YES!

Page 36: CoreData - there is an ORM you can like!

Why NOT to use Core Data?

•Programmer naivity

Page 37: CoreData - there is an ORM you can like!

•Programmer naivity➜ “My app isn’t complex enought”

= I am too lazy to learn it

Why NOT to use Core Data?

Page 38: CoreData - there is an ORM you can like!

•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?

Page 39: CoreData - there is an ORM you can like!

•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?

Page 40: CoreData - there is an ORM you can like!

•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?

Page 41: CoreData - there is an ORM you can like!

So?

Reading code is hardWriting code is easyWhy learn when we can re-invent?

Really? If this works in your world,Core Data is not for you...

Page 42: CoreData - there is an ORM you can like!

OK, but when seriously NO?

Update HUGE part of DB in one moment

Working with lots of records

➜ RSS Reader app

Page 43: CoreData - there is an ORM you can like!

Still not ready to use Core Data?

Read this: goo.gl/Flzrsk

Numbers here: goo.gl/lNFjdr

Page 44: CoreData - there is an ORM you can like!

HOW?

Page 45: CoreData - there is an ORM you can like!

.sqlite

Schema

App

Page 46: CoreData - there is an ORM you can like!

.sqlite

ORM Schema

App

Page 47: CoreData - there is an ORM you can like!

.sqlite

App

Core Data Schema

App

.sqlite Web Store

Page 48: CoreData - there is an ORM you can like!

.sqlite

App

Schema

App

.sqlite Web Store

NSManagedObjectContext

NSManagedObjectContext

NSManagedObjectModel

PersistentObjectStore

PersistentObjectStore

PersistentObjectStore

PersistentStore Coordinator

Page 49: CoreData - there is an ORM you can like!

.sqlite

App

Schema

App

.sqlite Web Store

NSManagedObjectNSManaged

ObjectNSManagedObject

NSManagedObjectContext

NSManagedObjectContext

NSManagedObjectModel

PersistentObjectStore

PersistentObjectStore

PersistentObjectStore

PersistentStore Coordinator

Page 50: CoreData - there is an ORM you can like!

...Complex ORM

=> Complex Setup

Page 51: CoreData - there is an ORM you can like!

Setup

Page 52: CoreData - there is an ORM you can like!

// 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] &amp;&amp; ![managedObjectContext save:&amp;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:&amp;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];}

Page 53: CoreData - there is an ORM you can like!

99 rows!

Page 54: CoreData - there is an ORM you can like!

Really ?!

Page 55: CoreData - there is an ORM you can like!

Core Data bites!

Page 56: CoreData - there is an ORM you can like!

The Cure

1) MagicalRecord

github.com/magicalpanda/MagicalRecord

Page 57: CoreData - there is an ORM you can like!

The Cure

1) MagicalRecord

github.com/magicalpanda/MagicalRecord

2) Mogenerator

github.com/rentzsch/mogenerator

Page 58: CoreData - there is an ORM you can like!

The Cure

1) MagicalRecord

github.com/magicalpanda/MagicalRecord

2) Mogenerator

github.com/rentzsch/mogenerator

+ CocoaPods (as usual)

Page 59: CoreData - there is an ORM you can like!

Magical Record

Page 60: CoreData - there is an ORM you can like!

Magical Record

Nice (Rails like) API on Core Data

Page 61: CoreData - there is an ORM you can like!

Magical Record

Nice (Rails like) API on Core Data

You still can dive in!

Page 62: CoreData - there is an ORM you can like!

// 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] &amp;&amp; ![managedObjectContext save:&amp;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:&amp;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

Page 63: CoreData - there is an ORM you can like!

99 rows!

Page 64: CoreData - there is an ORM you can like!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ [MagicalRecord

setupCoreDataStackWithStoreNamed:@"MyDatabase.sqlite"];

// ... return YES;} - (void)applicationWillTerminate:(UIApplication *)application{ [MagicalRecord cleanUp];}

MR

Page 65: CoreData - there is an ORM you can like!

11 rows!

Page 66: CoreData - there is an ORM you can like!

Fetch

Page 67: CoreData - there is an ORM you can like!

NSArray  *fetchedObjects;NSManagedObjectContext  *context  =  [self  

managedObjectContext];NSFetchRequest  *fetch  =  [[NSFetchRequest  alloc]  init];NSEntityDescription  *entityDescription  =  

[NSEntityDescription  entityForName:@"Person"    inManagedObjectContext:context];

[fetch  setEntity:entityDescription];[fetch  setPredicate:[NSPredicate  

predicateWithFormat:@"age  =  %d",  25]];NSError  *error  =  nil;fetchedObjects  =  [context  

executeFetchRequest:fetch  error:&error];

if([fetchedObjects  count]  ==  1)        return  [fetchedObjects  objectAtIndex:0];else        return  nil;

CD

Page 68: CoreData - there is an ORM you can like!

NSArray  *fetchedObjects;NSManagedObjectContext  *context  =  [self  

managedObjectContext];NSFetchRequest  *fetch  =  [[NSFetchRequest  alloc]  init];NSEntityDescription  *entityDescription  =  

[NSEntityDescription  entityForName:@"Person"    inManagedObjectContext:context];

[fetch  setEntity:entityDescription];[fetch  setPredicate:[NSPredicate  

predicateWithFormat:@"age  =  %d",  25]];NSError  *error  =  nil;fetchedObjects  =  [context  

executeFetchRequest:fetch  error:&error];

if([fetchedObjects  count]  ==  1)        return  [fetchedObjects  objectAtIndex:0];else        return  nil;

CD

Page 69: CoreData - there is an ORM you can like!

[Person findByAttribute:@"age" withValue:@25];

MR

Page 70: CoreData - there is an ORM you can like!

// Query to find all the persons store into the databaseNSArray *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 oldNSArray *personsWhoHave22 = [Person MR_findByAttribute:@"age"

withValue:[NSNumber numberWithInt:25]]; // Query to find the first person store into the databePerson *person = [Person MR_findFirst];

MR

Page 71: CoreData - there is an ORM you can like!

// Query to find all the persons store into the databaseNSArray *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 oldNSArray *personsWhoHave22 = [Person MR_findByAttribute:@"age"

withValue:[NSNumber numberWithInt:25]]; // Query to find the first person store into the databePerson *person = [Person MR_findFirst];

MR

Page 72: CoreData - there is an ORM you can like!

// Query to find all the persons store into the databaseNSArray *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 oldNSArray *personsWhoHave22 = [Person findByAttribute:@"age"

withValue:[NSNumber numberWithInt:25]]; // Query to find the first person store into the databePerson *person = [Person findFirst];

MR

Page 73: CoreData - there is an ORM you can like!

Background Op

Page 74: CoreData - there is an ORM you can like!

[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

Page 75: CoreData - there is an ORM you can like!

Mogenerator

Page 76: CoreData - there is an ORM you can like!

Mogenerator

Because Xcode sucks!

Page 77: CoreData - there is an ORM you can like!

Mogenerator

Because Xcode sucks!

_User for machineUser for human

Page 78: CoreData - there is an ORM you can like!

Mogenerator

Because Xcode sucks!

_User for machineUser for human

+ auto regen!

Page 79: CoreData - there is an ORM you can like!

But the docs sucks too!

It coves the basics, but I DO NEED to DIVE in!

goo.gl/9fNe0z

goo.gl/durEGR

Page 80: CoreData - there is an ORM you can like!

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!

Page 81: CoreData - there is an ORM you can like!

For-Mobile

http://srazy.info/for-mobile

Pondělí, 24. 3. 2014  19:00

Jakub HladíkAutomatic builds for iOS

=> Tomorrow!=> AfterPUB included!

Page 82: CoreData - there is an ORM you can like!

Tomáš Jukin@Inza

www.juicymo.cz@JuicymoCZ

Page 83: CoreData - there is an ORM you can like!

Tomáš Jukin@Inza

www.juicymo.cz@JuicymoCZ

goo.gl/jGLovj