Un super article d'uocram sur l'utilisation de Core Data. Pour aider de nombreux débutants à utiliser Core Data, Jean-Marc a créé un tutorial pas-à -pas en HTML.
je n'arrive pas à le faire fonctionner au niveau de la 2e page . j'ai cela...
2007-02-06 18:31:58.563 CodeEnStock[800] *** NSRunLoop ignoring exception 'Cannot perform operation since entity with name '(null)' cannot be found' that raised during posting of delayed perform with target 37dc30 and selector 'invokeWithTarget:'<br />
Dans IB, dans l'inspecteur, dans les Attributes du NSArrayController : ? as-tu bien renseigné l'Entity et non la Class? ? le nom de l'Entity doit être identique, y compris la casse, à celui donné dans le datamodel dans Xcode (un copier coller est prudent au début, notamment si le nom choisi est compliqué)
Tout d'abord merci beaucoup pour ce tutorial absolument génial, j'ai appris enormement grace à lui.
Pour aller plus loin, j'ai une question. J'ai bien un NSArrayController qui est bindé avec une entité qui contient plusieurs propriétés de plusieurs type. Ce que je voudrais, c'est qu'au lieu de créer une nouvelle instance vide de l'entité en question, je voudrais pouvoir initialiser les différentes propriétés à l'aide de Textfield et autres objets d'interface.
Donc quand j'appuie sur le bouton Add, il faudrait que le ArrayController recupère les données dans ces différents objets.
Est ce que c'est faisable avec le Binding ? si oui (ce serait super) comment ?
sinon est ce qu'il y a des exemple de code ? je débute en Objective C et j'ai encore du mal à l'utiliser.
Bon étant donné que je ne trouve rien avec le binding, je l'ai fait pas le code. J'ai fait un customArrayController dans lequel je lie les textfield et autres champs dont j'aurais besoin pour l'ajout. Puis j'ai implémenté une nouvelle fonction qui lit ces champs pour les mettre dans un nouveau NSManagedObject.
Pour récupérer le contexte, j'ai du aussi lier le AppDelegate généré par l'application.
J'ai l'impression que c'est un peu bourrin mais ça marche
Je met le code si ça en interesse certain (je débute en objective C, alors il y a peut etre des choses étranges)
fichier entete
<br />#import <Cocoa/Cocoa.h><br />#import "SimpleMoney_AppDelegate.h" // pour le contexte<br /><br />@interface AccountLineArrayController : NSArrayController <br />{<br /> IBOutlet SimpleMoney_AppDelegate *dataManager; // pour le contexte<br /> IBOutlet NSTextField *objet; // le champs qu'on veut recuperer<br />}<br /><br />- (IBAction) addWithData:(id)sender; // la nouvelle action<br /><br />@end<br />
Fichier source
<br />#import "AccountLineArrayController.h"<br /><br /><br />@implementation AccountLineArrayController<br /><br />- (IBAction) addWithData:(id)sender<br />{<br /> <br /> <br /> NSManagedObject * line = [NSEntityDescription<br /> insertNewObjectForEntityForName:@"AccountLine" // nom de l'entité<br /> inManagedObjectContext:[dataManager managedObjectContext]]; // contexte<br /> <br /> [line setValue:[objet stringValue] forKeyPath:@"object"]; // ajout de la valeur<br /><br /> [super addObject:line]; // ajout de l'objet dans le NSArrayController <br />}<br /><br />@end<br />
Merci beaucoup , cette page est effectivement très interessante et correspond exactement à ce que je cherchais, et je vais changer pour utiliser leur méthode (qui doit être surement plus propre que la mienne )
C'est marrant je n'est pas le même message au lancement de l'application. Voila ce que j'ai dans la console
2008-04-15 12:44:34.467 CodeEnStock[566:10b] An uncaught exception was raised<br />2008-04-15 12:44:34.468 CodeEnStock[566:10b] [<CodeEnStock_AppDelegate 0x13b4f0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key managedObjetContext.<br />2008-04-15 12:44:34.478 CodeEnStock[566:10b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<CodeEnStock_AppDelegate 0x13b4f0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key managedObjetContext.'<br />
"This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation."
Mon application s'ouvre sans les données précédemment entrées.
Cela doit venir de ta config., parce que chez moi cela fonctionne, lorsque j'ouvre à nouveau l'application les données précédemment rentrées sont bien là . On serait sur windows, je te dirais redémarre ::)...
J'ai trouvé, c'était à cause du fichier "~/Library/Application Support/CodeEnStock/CodeEnStock.xml", corrompu entre les différentes étapes du développement.
"The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store"
Lorsque l'on modifie le data model, en ajoutant une entity ou un attribut, le plus souvent cela se passe sans problème. Mais quand on en supprime une/un, ou que l'on en modifie le type, le genre de message cité ci-dessus apparaà®t, pour signaler que la structure du data model ne correspond pas à celle décrite dans le "store", fichier de la base de données enregistré là par défaut : /Users/moncompte/Bibliotheque/Applications Support/MonAppli/MonAppli.xml. Il peut être mécontent à l'ouverture de l'appli, ou lors de la sauvegarde automatique lors de la fermeture. Pendant la création de l'appli, à chaque modification de structure, il vaut mieux supprimer le fichier MonAppli.xml (ou .sql, selon votre choix de base de données). Il s'en crée un nouveau, correspondant à la nouvelle structure, mais vide de données!!!. Il vaut mieux attendre la fin de la mise au point de la structure avant de rentrer beaucoup de données, ou alors se créer dès le début, un importateur/exportateur indépendant de la structure (important des fichiers texte du format TTR par exemple).
Une "parse error" déclarée à la ligne 32 peut provenir d'une ligne qui se situe avant (oubli d'une accolade, parenthèse, .. ) d'un identificateur mal orthographié, d'un copier-coller avec des caractères invisibles qui restent, ... Le plus simple c'est de "nettoyer le code"
Bon, j'avance petit à petit (dur dur de faire cohabiter travail et passion), mais je suis bloqué sur la barre d'outils
j'ai une erreur :
CodeEnStock_AppDelegate.m:50: fatal error: method definition not in @implementation context
Pour le code :
<br /> [theDict setObject:item forKey:identifier];<br />}<br /><br />// méthode trouvée dans les exemples APPLE<br /><br />// This methode is required of NSToolbar delegates. It takes an identifier, and returns the matching NSToolbarItem.<br />// It also takes a parameter telling whether this toolbar item is going into an actual toolbar, or whether it's<br />// going to be displayed in a customization palette.<br />- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag<br />{<br />// We create and autorelease a new NSToolbarItem, and then go through the process of setting up its<br />// attributes from the master toolbar item matching that identifier in our dictionary of items.<br /> NSToolbarItem *newItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];<br /> NSToolbarItem *item=[toolbarItems objectForKey:itemIdentifier];<br /> <br /> [newItem setLabel:[item label]];<br /> [newItem setPaletteLabel:[item paletteLabel]];<br /> if ([item view]!=NULL)<br /> {<br /> [newItem setView:[item view]];<br /> }<br /> else<br /> {<br /> [newItem setImage:[item image]];<br /> }<br /> [newItem setToolTip:[item toolTip]];<br /> [newItem setTarget:[item target]];<br /> [newItem setAction:[item action]];<br /> [newItem setMenuFormRepresentation:[item menuFormRepresentation]];<br /> // If we have a custom view, we *have* to set the min/max size - otherwise, it'll default to 0,0 and the custom<br /> // view won't show up at all! This doesn't affect toolbar items with images, however.<br /> if ([newItem view]!=NULL)<br /> {<br /> [newItem setMinSize:[[item view] bounds].size];<br /> [newItem setMaxSize:[[item view] bounds].size];<br /> }<br /> <br /> return newItem;<br />}<br />
et plus précisement les lignes :
<br />- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag<br />{<br />// We create and autorelease a new NSToolbarItem, and then go through the process of setting up its<br />// attributes from the master toolbar item matching that identifier in our dictionary of items.<br /> NSToolbarItem *newItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];<br />
l'erreur apparaà®t au niveau de l'ouverture du crochet "{"
"The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store"
Lorsque l'on modifie le data model, en ajoutant une entity ou un attribut, le plus souvent cela se passe sans problème. Mais quand on en supprime une/un, ou que l'on en modifie le type, le genre de message cité ci-dessus apparaà®t, pour signaler que la structure du data model ne correspond pas à celle décrite dans le "store", fichier de la base de données enregistré là par défaut : /Users/moncompte/Bibliotheque/Applications Support/MonAppli/MonAppli.xml. Il peut être mécontent à l'ouverture de l'appli, ou lors de la sauvegarde automatique lors de la fermeture. Pendant la création de l'appli, à chaque modification de structure, il vaut mieux supprimer le fichier MonAppli.xml (ou .sql, selon votre choix de base de données). Il s'en crée un nouveau, correspondant à la nouvelle structure, mais vide de données!!!. Il vaut mieux attendre la fin de la mise au point de la structure avant de rentrer beaucoup de données, ou alors se créer dès le début, un importateur/exportateur indépendant de la structure (important des fichiers texte du format TTR par exemple).
Ok, mais ne serait il pas possible d'automatiser cet effacement à chaque build par un moyen ou un autre... ?
Réponses
? as-tu bien renseigné l'Entity et non la Class?
? le nom de l'Entity doit être identique, y compris la casse, à celui donné dans le datamodel dans Xcode (un copier coller est prudent au début, notamment si le nom choisi est compliqué)
Cf copie d'écran jointe.
[Fichier joint supprimé par l'administrateur]
Tout d'abord merci beaucoup pour ce tutorial absolument génial, j'ai appris enormement grace à lui.
Pour aller plus loin, j'ai une question. J'ai bien un NSArrayController qui est bindé avec une entité qui contient plusieurs propriétés de plusieurs type. Ce que je voudrais, c'est qu'au lieu de créer une nouvelle instance vide de l'entité en question, je voudrais pouvoir initialiser les différentes propriétés à l'aide de Textfield et autres objets d'interface.
Donc quand j'appuie sur le bouton Add, il faudrait que le ArrayController recupère les données dans ces différents objets.
Est ce que c'est faisable avec le Binding ? si oui (ce serait super) comment ?
sinon est ce qu'il y a des exemple de code ? je débute en Objective C et j'ai encore du mal à l'utiliser.
Merci ::)
Pour récupérer le contexte, j'ai du aussi lier le AppDelegate généré par l'application.
J'ai l'impression que c'est un peu bourrin mais ça marche
Je met le code si ça en interesse certain (je débute en objective C, alors il y a peut etre des choses étranges)
fichier entete
Fichier source
Peut être cette adresse te sera-t-elle utile :
http://developer.apple.com/documentation/Cocoa/Conceptual/NSPersistentDocumentTutorial/index.html#//apple_ref/doc/uid/TP40001799
C'est un exemple d'implémentation de la saisie d'une nouvelle entrée par l'intermédiaire d'une "sheet" dans un managed object context séparé.
Bonne chance
cette page est effectivement très interessante et correspond exactement à ce que je cherchais, et je vais changer pour utiliser leur méthode (qui doit être surement plus propre que la mienne )
Que ce passe t il ? ou quel erreur j' ai commise ?
Merci
Cordialement.
J' ai compris
Merci
Cordialement .
"The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store"
J'utilise Xcode 3, voici le projet : http://chkdsks.free.fr/CodeEnStock.zip
Merci
:why?:
Voila ce que j'ai dans la console
Si ça peut faire avancer le schmilblick ?
Mais ce n'est pas la même erreur :P, j'ai toujours dans la console:
"This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation."
Mon application s'ouvre sans les données précédemment entrées.
Nouvelle version : http://chkdsks.free.fr/CodeEnStock.zip
Il a dut t'arriver les pires misères pour remarquer aussi vite ce genre d'erreur, non ?
Sinon:
Il suffit de cliquer dans le menu edit -> find dans le projet
et de remplacer objet par object .
On recompile et ça marche...
Cela doit venir de ta config., parce que chez moi cela fonctionne, lorsque j'ouvre à nouveau l'application les données précédemment rentrées sont bien là . On serait sur windows, je te dirais redémarre ::)...
Oh là là .... ;D si tu savais
Bienvenu dans le club
Lorsque l'on modifie le data model, en ajoutant une entity ou un attribut, le plus souvent cela se passe sans problème.
Mais quand on en supprime une/un, ou que l'on en modifie le type, le genre de message cité ci-dessus apparaà®t, pour signaler que la structure du data model ne correspond pas à celle décrite dans le "store", fichier de la base de données enregistré là par défaut : /Users/moncompte/Bibliotheque/Applications Support/MonAppli/MonAppli.xml.
Il peut être mécontent à l'ouverture de l'appli, ou lors de la sauvegarde automatique lors de la fermeture.
Pendant la création de l'appli, à chaque modification de structure, il vaut mieux supprimer le fichier MonAppli.xml (ou .sql, selon votre choix de base de données). Il s'en crée un nouveau, correspondant à la nouvelle structure, mais vide de données!!!.
Il vaut mieux attendre la fin de la mise au point de la structure avant de rentrer beaucoup de données, ou alors se créer dès le début, un importateur/exportateur indépendant de la structure (important des fichiers texte du format TTR par exemple).
Je suis en train de suivre ce tuto mais j'ai une erreur lors de la 3ème page :
CodeEnStock_AppDelegate.h:32: error: parse error before '{' token
code incriminer :
je ne comprend pas bien mon erreur, est ce que quelqu'un pourrai m'orienter ?
Stounfr
Le plus simple c'est de "nettoyer le code"
mais je ne vois pas ou j'ai fait une bourde.
Voici le code source de mon CodeEnStock_AppDelegate.h
et voici mon CodeEnStock_AppDelegate.m
C'est quand même énervant de ne pas voir ses erreurs...
:why?:
Et en plus j'ai compris
j'ai une erreur :
CodeEnStock_AppDelegate.m:50: fatal error: method definition not in @implementation context
Pour le code :
et plus précisement les lignes :
l'erreur apparaà®t au niveau de l'ouverture du crochet "{"
Le message est clair :
method definition not in @implementation context
La méthode n'est pas là où il faut , entre
@implementation CodeEnStock_AppDelegate
et
@end
Peut-être le @end n'existe pas, où n'est pas lue à cause d'une accolade, d'une parenthèse, d'un point-virgule en trop ou en pas assez.
CodeEnStock_AppDelegate.m:36: warning: 'NSMenuItem' may not respond to '-setMenuFormRepresentation:'
mais ca fonctionne...
Encore merci...
setMenuFormRepresentation --> setMenuFromRepresentation
Ok, mais ne serait il pas possible d'automatiser cet effacement à chaque build par un moyen ou un autre... ?