Core data basic Workshop slides NSSpain 2013

83
Diego Freniche / @dfreniche / http://www.freniche.com Core Data Workshop

description

My slides used at NSSpain 2013 on Core Data

Transcript of Core data basic Workshop slides NSSpain 2013

Page 1: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Core Data Workshop

Page 2: Core data basic Workshop slides NSSpain 2013

Diego Freniche: programmer & teacher

Page 3: Core data basic Workshop slides NSSpain 2013

Diego Freniche: programmer & teacher

• @dfreniche

• Freelance Mobile developer: iOS/Android/BB10/webOS/...

• In a former life Java Certifications Collector: SCJP 1.5, SCJP 1.6, SCWCD 1.5, SCBCD 1.3

• Some languages: BASIC, PASCAL, C, C++, Delphi, COBOL, Clipper, Visual Basic, Java, JavaScript, Objective-C

Hello, World!

Page 4: Core data basic Workshop slides NSSpain 2013

Before we start...

Page 5: Core data basic Workshop slides NSSpain 2013

Before we start...

• Switch OFF phones

Page 6: Core data basic Workshop slides NSSpain 2013

Before we start...

• Switch OFF phones

• Been here is funny

Page 7: Core data basic Workshop slides NSSpain 2013

Before we start...

• Switch OFF phones

• Been here is funny

• ¡Live the moment!¡Carpe diem!

Page 8: Core data basic Workshop slides NSSpain 2013

Before we start...

• Switch OFF phones

• Been here is funny

• ¡Live the moment!¡Carpe diem!

• Ask me a lot. Don’t yawn

Page 9: Core data basic Workshop slides NSSpain 2013

Our objective: BUILD things

Page 10: Core data basic Workshop slides NSSpain 2013

What you need (checklist)

• a Mac with OS X capable of running Xcode 4.6.1

• last Xcode 4 installed 4.6.1

• You can also use prerelease software, if you are a registered Apple developer. No support then, sorry :-D

• SimPholders installed: http://simpholders.com

• SQLLite database browser: http://sqlitebrowser.sourceforge.net

• (optional) set $HOME/Library folder visible, using (from a Terminal)

Page 11: Core data basic Workshop slides NSSpain 2013

Diego Freniche / http://www.freniche.com

Core Data: developer’s first impression

Page 12: Core data basic Workshop slides NSSpain 2013

Diego Freniche / http://www.freniche.com

Core Data: developer’s first impression

Page 13: Core data basic Workshop slides NSSpain 2013

Diego Freniche / http://www.freniche.com

Page 14: Core data basic Workshop slides NSSpain 2013

Diego Freniche / http://www.freniche.com

Core Data in 547 easy steps slide 6/320

Page 15: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Core Data terms

• Entity

• an entity in our model == Object in memory == row in table

• Attribute

• Relationship

• Object graph

http://ogre.berniecode.com/ogre_white_paper

Page 16: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Core Data terms

• Entity

• an entity in our model == Object in memory == row in table

• Attribute

• Relationship

• Object graph

http://ogre.berniecode.com/ogre_white_paper

Page 17: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

To get the most out of Core Data

• KVC, KVO

• ARC, memory management

• delegate & MVC patterns

• singletons are evil (more or less)

Page 18: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Core Data Hello World!

Page 19: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

The Problem

• Objet - Relational impedance

• SQL: 70s/80s

• OOP: 80s-

Page 20: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 1: composition

Person+name: String

+idCard: idCard

+bankAccout: bankAccount

Page 21: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 1: composition

Person+name: String

+idCard: idCard

+bankAccout: bankAccount

idCard

+number: int+letter: char

+checkLetter()

Page 22: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 1: composition

id name idCardPerson

+name: String

+idCard: idCard

+bankAccout: bankAccount

idCard

+number: int+letter: char

+checkLetter()

Page 23: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 1: composition

id name idCardPerson

+name: String

+idCard: idCard

+bankAccout: bankAccount

idCard

+number: int+letter: char

+checkLetter()

VARCHAR

Page 24: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 1: composition

id name idCardPerson

+name: String

+idCard: idCard

+bankAccout: bankAccount

idCard

+number: int+letter: char

+checkLetter()

VARCHAR ¿?

Page 25: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Employee

+empNumber: int

Person

+name: String+idCard: idCard

Exhibit 2: inheritance

Page 26: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Employee

+empNumber: int

Person

+name: String+idCard: idCard

Exhibit 2: inheritance

Politician

+moneyTaken: double

Page 27: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Employee

+empNumber: int

Person

+name: String+idCard: idCard

Exhibit 2: inheritance

Hyena

Politician

+moneyTaken: double

Page 28: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Exhibit 3: collection modelling

Person

+name: String

+bills: Bill[]

Bill

0..*1

http://en.wikipedia.org/wiki/First_normal_form

Page 29: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Relational World

• tables

• cartesian products

• rows/ columns

• normal forms

• Objects

• object collections

• composition

• inheritance

OO World

Page 30: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Relational World

• tables

• cartesian products

• rows/ columns

• normal forms

• Objects

• object collections

• composition

• inheritance

OO World

Page 31: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

The solution: ORM

• Object Relational Mapper

• Hibernate (Java, .Net)

• Core Data (Cocoa)

• Core Data is our model

• can persist our objects in several ways

Page 32: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

The Core Data Stack

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object Model

Page 33: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Managed Object Context

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object Model

Page 34: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Our Model

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSManagedObject

NSObject

PersistedIn memory only

Page 35: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Managed Object Context: MOC

• Managed Object Context: in-memory space where CD manages all our model’s objects.

• All CRUD is done against a MOC. We persist data using save:

• Our model’s objects are Managed Objects.

• The MOC needs a Persistent Store Coordinator to save the object graph in persistent store.

Page 36: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Managed Object Model

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object Model

Page 37: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Managed Object Model

• Maps our model objects into database tables.

• Objects == NSManagedObject

• Classes == NSEntityDescription

• We describe our App entities inside a MOM

• stored inside .xcdatamodeld files in Xcode. Compiles into .momd

• graphic editor / class generator (dumb)

Page 38: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Managed Object Model

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object Model

Page 39: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Persistent Store Coordinador

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object Model

Makes the mapping between our App’s objects and the physical storage inside the Persistent Object Store.

99% time we’ll work with ONE Object Store, but it’s possible use more than one. For example, a sqlite DB with recipes and another DB with notes, stars, etc. Coordinator: single façade to work with different Stores.

A managed object context can then create an object graph based on the union of all the data stores the coordinator covers

Coordinator: serializes operations

Page 40: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Persistent Object Store

Managed Object Context

Persistent Store Coordinator

Persistent Object Store

Managed Object ModelNSXMLStoreType (XML only OS X, bad performance)NSSQLiteStoreType (partial object graph in memory)NSBinaryStoreType (kind of NIBs, poor performance)NSInMemoryStoreType (good for testing)

Makes the mapping between our App’s objects and the physical storage inside the Persistent Object Store.

Supported Store Types

Page 41: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

SQL in SQLite

• http://sqlite.org/lang.html

• We can see generated SQL: -com.apple.CoreData.SQLDebug 1

• Schemes > Edit Scheme > Test > Arguments

Page 42: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

1

2

3

Page 43: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Accessing SQLite

sqlitebrowser.sourceforge.net

Look in:

/Users/<usuario>/Library/Application Support/iPhone Simulator/<versión>/Applications/<ID App>/Documents/<archivo SQLite>

Page 44: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

DDL: Data Definition Language

• CREATE DATABASE, CREATE TABLE, CREATE INDEX, ALTER TABLE, DROP INDEX, ...

• All written by Core Data

• We DO NOT have to create anything: neither tables nor database

• If we make changes, Core Data alters tables, columns, indexes...

Page 45: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

DDL: Data Definition Language

• CREATE DATABASE, CREATE TABLE, CREATE INDEX, ALTER TABLE, DROP INDEX, ...

• All written by Core Data

• We DO NOT have to create anything: neither tables nor database

• If we make changes, Core Data alters tables, columns, indexes...

Page 46: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Modelling

We need a Data Model file to “draw” our model

1st, create all our model’s entities, then add attributes

Can subclass NSManagedObject to use compiler-time name checking, Xcode’s autofill,...

Page 47: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Modelling

• New model versions: Editor > Add Model Version

• Model (.xcdatamodeld) is a folder

• Last version has no number. Oldest with higher number. WTF, Apple! (WTF: What a Tricky Fact)

• 1st time we access model it creates persintent store lazily

Select THIS

Page 48: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Versioning and changes

• Activate always lightweight migration

• If we make changes to the model, not changing version, version used in the model and version used to create DB doesn’t match: delete DB.

• Reseting Content and Settings.. in Simulator

• delete (by hand) .sqlite file

Page 49: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSManagedObject

NSManagedObject

NSManagedObjectContext

NSEntityDescription

Page 50: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSManagedObject

• base class implementing all “basic” object model behavior

• We can NOT use Core Data with NSObject, we HAVE TO use NSManagedObject

• Our model classes inherit from NSManagedObject

• not mandatory, but...

• allows us to add logic, use @property, get notifications...

• have to be properly configured

Page 51: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Entities Design

• Always add field order

• Try to create a good UML diagram at first

• Have an NSString constant with every Entity’s name inside .h

Page 52: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Extend NSManagedObject

• Editor > Create NSManagedObject subclass...

• creates @dynamic properties

• getter / setter generated in runtime (@property in compile time)

• Core Data doesn’t know at compile time if the persistent store is going to be XML or a DB (or in-memory)

Page 53: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Extend NSManagedObject

• overwrite init to call designated initializer

Page 54: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Extend NSManagedObject

• overwrite init to call designated initializer

-(id)init {

NSManagedObjectContext *context = [[CoreDataStack coreDataStack] managedObjectContext];

return [self initWithEntity:[NSEntityDescription entityForName:kRETROITEM_ENTITY inManagedObjectContext:context ] insertIntoManagedObjectContext:context];

}

Page 55: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Validate Properties

• One for every property, if we want it

• Passing parameter by reference

• It should return YES if validation is passed

Page 56: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Validate Properties

• One for every property, if we want it

• Passing parameter by reference

• It should return YES if validation is passed

-(BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError;

Page 57: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Validator for operations

• First thing: must call [super ...]

• Useful to check business rules (using several properties)

Page 58: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Validator for operations

• First thing: must call [super ...]

• Useful to check business rules (using several properties)

- (BOOL)validateForDelete:(NSError **)error

- (BOOL)validateForInsert:(NSError **)error

- (BOOL)validateForUpdate:(NSError **)error

Page 59: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Support for KVO

• Good for Faults

Page 60: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Support for KVO

• Good for Faults

- (void)willAccessValueForKey:(NSString *)key

Page 61: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Inserting Entities (INSERT INTO)

insertNewObjectForEntityForName context save

Context

Page 62: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Inserting Entities (INSERT INTO)

// using NSEntityDescription. Pass: entity name and context

[NSEntityDescription insertNewObjectForEntityForName:@”MyEntity” inManagedObjectContext:context];

[retroItem setValue:@"Spectrum 48K" forKey:@"name"];

[retroItem setValue:@100.00 forKey:@"acquisitionCost"];

[retroItem setValue:[NSDate new] forKey:@"dateAcquired"];

insertNewObjectForEntityForName context save

Context

Page 63: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Fetching entities (SELECT)

• Query with NSFetchRequest

• SELECT by definition is unordered

• At least we need to provide

• entity

• order by

Page 64: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Step by Step fetch (Select)

1

2

3

4

5

6

Page 65: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Step by Step fetch (Select)

NSManagedObjectContext *context = [[CoreDataStack coreDataStack] managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:kRETRO_ITEM_ENTITY inManagedObjectContext:context];

[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];

[fetchRequest setSortDescriptors:@[sortDescriptor]];

NSError *error = nil;

NSArray *distincResults = [context executeFetchRequest:fetchRequest error:&error];

1

2

3

4

5

6

Page 66: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Order querys

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fecha_max" ascending:YES];

NSManagedObject returned inside NSArray are unordered unless otherwise we provide NSSortDescription.

1st, we create the sort descriptor

[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Then we add to our NSFetchRequest the sort descriptors array:

Page 67: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Filtering querysNSManagedObjectContext *moc = [self managedObjectContext];

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc];

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];[request setEntity:entityDescription];

NSNumber *minimumSalary = ...;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];

[request setPredicate:predicate];

NSError *error = nil;

NSArray *array = [moc executeFetchRequest:request error:&error];

NSFetchRequest returns an array of NSManagedObject. We can use a NSPredicate to filter.

Filter/NSPredicate acts here as the SQL WHERE clause.

We need to add that query with setPredicate.

Page 68: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Delete Entities (DELETE)

+ (void)deleteInstancesForEntityName:(NSString *)entityName inContext:(NSManagedObjectContext *)context {

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];

[fetch setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:context]]; NSError *error = nil; NSArray *dataObjects = [context executeFetchRequest:fetch error:&error]; for (NSManagedObject *dataObject in dataObjects) { [context deleteObject:dataObject]; }

NSError *saveError = nil; [context save:&saveError];}

Page 69: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Object identificator

Page 70: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Object identificator

NSManagedObjectID *moID = [managedObject objectID];

-(NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID

error:(NSError **)error

Page 71: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Accessing Properties

Sometimes we don’t want the whole object (NSManagedObject) only the value of a property applying a function (max, min, etc.).

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];

[request setEntity:entity];

1. Create NSFetchRequest as usual

[request setResultType:NSDictionaryResultType];

2. Tell NSFetchRequest to return NSDictionary instead NSArray:

NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"creationDate"];

NSExpression *minExpression = [NSExpression expressionForFunction:@"min:" arguments:[NSArray arrayWithObject:keyPathExpression]];

3. Define the field to calc upon (NSExpression), then the function

Page 72: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Accessing Properties

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];

[expressionDescription setName:@"minDate"];

[expressionDescription setExpression:minExpression];

[expressionDescription setExpressionResultType:NSDateAttributeType];

4. Create a NSExpressionDescription:

[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];

5. Set in the query the properties to fetch

if ([objects count] > 0) { NSLog(@"Minimum date: %@", [[objects objectAtIndex:0] valueForKey:@"minDate"]);}

6. Access our result:

Page 73: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Relationship example

NSManagedObjectContext *context = [self managedObjectContext];

NSManagedObject *failedBankInfo = [NSEntityDescription insertNewObjectForEntityForName:@"FailedBankInfo" inManagedObjectContext:context];

[failedBankInfo setValue:@"Test Bank" forKey:@"name"];[failedBankInfo setValue:@"Testville" forKey:@"city"];[failedBankInfo setValue:@"Testland" forKey:@"state"];

NSManagedObject *failedBankDetails = [NSEntityDescription insertNewObjectForEntityForName:@"FailedBankDetails" inManagedObjectContext:context];

[failedBankDetails setValue:[NSDate date] forKey:@"closeDate"];[failedBankDetails setValue:[NSDate date] forKey:@"updateDate"];[failedBankDetails setValue:[NSNumber numberWithInt:12345] forKey:@"zip"];[failedBankDetails setValue:failedBankInfo forKey:@"info"];

[failedBankInfo setValue:failedBankDetails forKey:@"details"];

NSError *error;

if (![context save:&amp;error]) { NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);}

Escritura

Page 74: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Relationship example

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"FailedBankInfo" inManagedObjectContext:context];

[fetchRequest setEntity:entity];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

for (NSManagedObject *info in fetchedObjects) {

NSLog(@"Name: %@", [info valueForKey:@"name"]);

NSManagedObject *details = [info valueForKey:@"details"]; NSLog(@"Zip: %@", [details valueForKey:@"zip"]);}

Read

Page 75: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

• Controller without interface

• Purpose: “feed” with data an UITableView

• Protocol NSFetchedResultsControllerDelegate

• section “Typical Use”: there’s the code found in template

• connected to a Context: if there are changes of any object inside that context it receives a notification and updates automatically

Page 76: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

SQLite

UITableView

Page 77: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

SQLite

UITableView

???

Page 78: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

Context

NSManagedObject

NSManagedObject

NSManagedObject

SQLite

UITableView

???

Page 79: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

Context

NSManagedObject

NSManagedObject

NSManagedObject

SQLite

UITableView NSFetchedResultsController

???

delegate

Page 80: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

Context

NSManagedObject

NSManagedObject

NSManagedObject

SQLite

UITableView NSFetchedResultsController

???

delegate

Page 81: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

NSFetchedResultsController

Context

NSManagedObject

NSManagedObject

NSManagedObject

SQLite

UITableView NSFetchedResultsController

delegate

Page 82: Core data basic Workshop slides NSSpain 2013
Page 83: Core data basic Workshop slides NSSpain 2013

Diego Freniche / @dfreniche / http://www.freniche.com

Attributions• http://www.flickr.com/photos/paldies/85684217/

• http://www.flickr.com/photos/56380734@N05/6808753611/

• http://www.flickr.com/photos/msimdottv/4339697089/

• http://www.flickr.com/photos/mobilestreetlife/4179063482/

• http://www.flickr.com/photos/owldreams/4428782193/

• http://www.flickr.com/photos/miss_pupik/73160522/

• http://kfannerd713.deviantart.com/art/UNICORN-PUKING-RAINBOWS-WHAAAA-152117816

• http://www.flickr.com/photos/wwworks/4759535950/

• http://www.flickr.com/photos/barto/28135419/sizes/l/in/photolist-3ucFr-7aiwZ-aqWUu-bLebi-cDeVC-jt2YW-jWW1t-kQ25f-m86XP-swafK-yHMbE-yHMcc-yHMda-