cocoaheads toulouse - getting to the core of core data

Post on 06-Jul-2015

2.432 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Introduction à CoreData

Partie 1

Jérome AlvesRomain BricheMichel Moreau

Partie 1

• Présentation des concepts

• Intégration

• Modélisation

• Utilisation basique

Partie 11

• Concepts avancés

• Contextes multi-thread

• Migrations

• Performance

Introduction

Introduction

• Qu’est-ce que CoreData

• Framework de gestion de persistance

Introduction

• Qu’est-ce que CoreData

• Framework de gestion de persistance

• Techniques de gestion de persistance

• Fichiers

• Property List

• SQL

Eléments fondamentaux

Eléments fondamentaux

Entités

Eléments fondamentaux

EntitésAttributs

Eléments fondamentaux

Entités

Relations

Attributs

Types de données

non-persistant persistant

Type de base NSObject NSManagedObject

Attributs * * (mais c’est compliqué)

Méthodes * *

La pile CoreData

La pile CoreData

Managed Object Model

A collection of entity descriptions

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

Persistent Object Store

A collection of object data

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

Persistent Object Store

A collection of object data

Store File

La pile CoreData

Core Data vs MVC

Model

Controller View

CoreData

Core Data vs MVC

Model

Controller View

Mo

de

l

CoreData

Core Data vs MVC

Model

Controller View

Mo

de

l

CoreData

Core Data vs MVC

Model

Controller View

Cloud

Création du modèle

Fichier .xcdatamodel

Le Model Editor

Création d’entités

Créations d’attributs

Types d’attributs

‣Non défini‣Entiers‣Décimal- plus précis‣Double‣Flottant

‣Chaîne de caractères‣Booléen‣Date‣Binaire‣Transformable

Propriétés‣Optionnel‣Transcient- non persisté- requiert accesseurs- mofications observables- migration facile‣Indexé- performance

Relations

Relations inverses

Règles de suppression

‣Pas d’action‣Nullité‣Cascade‣Déni- impossible de supprimé si la relation existe encore

Propriétés avancées

‣Fetched properties‣Fetch requets

Et maintenant?

Exemple d’utilisation// Créer de la requêteNSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:[NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:moc]];

// Récupération d’un objetNSError *error = nil;NSManagedObject *enfant = [[moc executeFetchRequest:request error:&error] lastObject];[request release];

// Création d’un objet if (!enfant) { enfant = [NSEntityDescription insertNewObjectForEntityForName:@"Enfant" inManagedObjectContext:moc];}

// Passage de valeur[enfant setValue:@"Harry" forKey:@"prenom"];[enfant setValue:@"Potter" forKey:@"nom"];

KVC‣Accès “générique” à un attribut d’un objet- exemple: attribut “prenom” de l’objet “enfant”‣Binding pendant le Runtime- nom de l’attribut non connu au moment de la compilation- Erreur “Unknown value for key ...”‣Logique- Cherche pour un accesseur- Cherche pour une variable- Cherche valueForUndefinedKey:/setValueForUndefinedKey:‣Compatibilité- OBJ-C 2.0 @property/@synthesize

KVO

‣Notifications- exemple: changement de la valeur d’un attribut‣Méthodes- willAccessValueForKey: / didAccessValueForKey:- willChangeValueForKey: / didChangeValueForKey:- ...

KVO/KVC

‣NSObject -> OK‣NSManagedObject -> !OK

Intérêt Sous-Classe

‣Compatible KVC- prenom- setPrenom:- ...‣Création de classes personnalisées- nomComplet- ...

Sous-classes

Sous-classes

Header

@class Parent;

@interface Enfant : NSManagedObject {@private// Pas de variables}@property (nonatomic, retain) NSString * nom;@property (nonatomic, retain) NSString * prenom;@property (nonatomic, retain) NSDate * dateNaissance;@property (nonatomic, retain) NSSet* parents;

@end

Implementation#import "Enfant.h"#import "Parent.h"

@implementation Enfant@dynamic nom, prenom, dateNaissance, parents;

- (void)addParentsObject:(Parent *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:@"parents" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [[self primitiveValueForKey:@"parents"] addObject:value]; [self didChangeValueForKey:@"parents" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [changedObjects release];}

- (void)removeParentsObject:(Parent *)value {...}- (void)addParents:(NSSet *)value {...}- (void)removeParents:(NSSet *)value {...}

@end

Sous-classes

Exemple d’utilisation// Créer de la requêteNSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:[NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:moc]];

// Récupération d’un objetNSError *error = nil;Enfant *enfant = [[moc executeFetchRequest:request error:&error] lastObject];[request release];

// Création d’un objet if (!enfant) { enfant = [NSEntityDescription insertNewObjectForEntityForName:@"Enfant" inManagedObjectContext:moc];}

// Passage de valeur[enfant setPrenom:@"Harry"];[enfant setNom:@"Potter"];

NE PAS “OVERRIDER”

‣-init- ne fonctionne pas comme -init de NSObject- modifie la structure mais les données sont absentes‣-dealloc- Ne se produit pas quand espéré- Core Data “gère la gestion mémoire” au sein de la classe

ALTERNATIVES

‣-awakeFromInsert- lors de la création- appelée 1 seule et unique fois‣-awakeFromFetch- appelée à chaque fois que l’objet est retourné (non créé)‣-willTurnIntoFault- appelée lors que l’objet est réellement détruit‣...- voir la documentation

Attention à la modification du modèle

Démo

Opérations de base

• Ajouter un élément

• Supprimer un élément

• Créer une requête

• Prédicat

• Sort Descriptor

• Sauvegarde

Insertion d’élément

// Demande de création d’un managedObject au contexte, dans une entité précise

Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];

Suppression d’élément// Obtenir l’objet a supprimerNSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];

// Demande de suppresion au contexte[managedObjectContext deleteObject:eventToDelete];

Les requêtes

• Une requête :

• Un prédicat

• Un sortDescriptor

• Execution

Requête

Les requêtes

Requête

Les requêtes

Prédicat

Requête

Les requêtes

Prédicat

Requête

Les requêtes

Prédicat

SortDescriptor

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Entité

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Entité

Les requêtes

// Créer de la requêteNSFetchRequest *request = [[NSFetchRequest alloc] init];

// Obtenir l’entitéNSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];

[request setEntity:entity];

// Créer un prédicatNSPredicate *predicate = [NSPredicate predicateWithFormat:    @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];

[request setPredicate:predicate];

Les requêtes// Créer un sortDescriptorNSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"creationDate" ascending:NO];

NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[request setSortDescriptors:sortDescriptors];

[sortDescriptors release];[sortDescriptor release];

// Exécuter la requêteNSError *error = nil;NSArray *array = [moc executeFetchRequest:request error:&error];

if (array == nil){    // Deal with error...}

Sauvegarde du contexte

Managed Object Context

Managed Object ModelPersistent Store Coordinator

Persistent Object Store

MOMO

MOMO

MO

Store File

Sauvegarde du contexte

Managed Object Context

Managed Object ModelPersistent Store Coordinator

Persistent Object Store

MOMOMOMOMO

Store File

Sauvegarde du contexte

// NSError *error = nil;

if (![managedObjectContext save:&error]) {

// Handle the error.

}

Démo

NSFetchedResultsController‣Seulement pour iOS- Pas (encore) sur Mac‣Observations des changements- Notifie le contrôleur qu’il doit rafraîchir l’UI- Notifications sélectives => meilleure performance- Objets/propriétés‣-willTurnIntoFault- appelée lors que l’objet est réellement détruit‣...- voir la documentation

Trève de blabla

@interface ViewController : UITableViewController <NSFetchedResultsControllerDelegate> {" NSFetchedResultsController *fetchedResultsController;" NSManagedObjectContext *moc;}

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSManagedObjectContext *moc;

- (NSFetchedResultsController*)fetchedResultsController { if (_fetchedResultsController) return _fetchedResultsController; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:[self moc]]; [fetchRequest setEntity:entity]; [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"nom==%@",@"Potter"]]; [fetchRequest setFetchBatchSize:20]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"prenom" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; NSFetchedResultsController *frc = nil; frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self moc] sectionNameKeyPath:nil cacheName:@"Potter"]; [frc setDelegate:self]; [self setFetchedResultsController:frc]; [frc release], frc = nil; [fetchRequest release], fetchRequest = nil; [sortDescriptor release], sortDescriptor = nil; [sortDescriptors release], sortDescriptors = nil; return _fetchedResultsController;}

NSFetchedResultsControllerDelegate

‣ -controllerWillChangeContent: ‣ -controller:didChangeSection:atIndex:forChangeType:‣ -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:‣ -controllerDidChangeContent:

NSFetchedResultsControllerDelegate

Pour aller plus loin

‣Les opérations- @sum, @distincUnionOfSets, etc...‣Les migrations- automatique, mapping model, manuelle‣Notions avancées- multi-threading, données binaire, faulting, synchronisation‣Performance‣Nouveautés iOS5- iCloud, concurrence, protection, …

Suggestions de ressources

Nouveautés iOS5iCloud, concurrence, protection, …

Merci

top related