Archivage & Co
gibet_b
Membre
Comme je l'ai indiqué dans un précédent post, je suis en plein découverte du Cocoa. Pour cela j'utilise le livre "Cocoa par la pratique" qui a du être utilisé par un certain nombre d'entre vous. Cependant je me pose des questions dont je n'arrive pas à trouver la réponse.
Je suis au chapitre 13 et j'essaie de répondre à l'exercice qui demande de pouvoir dessiner des ovales (j'ai remplacé par des traits) en choisissant leur emplacement et leur taille, et éventuellement, d'implémenter l'enregistrement et la lecture des fichiers.
Je suis donc retourné en arrière et relu le chapitre sur l'Archivage. Le problème c'est que l'implémentation dans ce chapitre se fait dans une application de type Document Based. Or mon application est une "Cocoa Application". Aussi je ne sais pas où implémenter les méthodes initWithcoder, encodeWithCoder (j'ai pensé à PaintView.m mais j'ai un problème avec le initWithCoder qui vient remplacer initWithFrame) et encore moins dataRepresentationOfType et loadDataRepresentation...
J'ai regardé le tutoriel "Echecs" qui traite de l'enregistrement des parties, et qui est une "Cocoa Application" mais cela n'utilise pas l'archivage mais une autre méthode d'enregistrement, d'après ce que j'ai compris. Quelles sont donc les différences ? Peut-on utiliser l'archivage avec un application qui n'est pas "Document Based" ?
Pardon pour toutes ces questions de newbie, et merci de l'accueil !
Je suis au chapitre 13 et j'essaie de répondre à l'exercice qui demande de pouvoir dessiner des ovales (j'ai remplacé par des traits) en choisissant leur emplacement et leur taille, et éventuellement, d'implémenter l'enregistrement et la lecture des fichiers.
Je suis donc retourné en arrière et relu le chapitre sur l'Archivage. Le problème c'est que l'implémentation dans ce chapitre se fait dans une application de type Document Based. Or mon application est une "Cocoa Application". Aussi je ne sais pas où implémenter les méthodes initWithcoder, encodeWithCoder (j'ai pensé à PaintView.m mais j'ai un problème avec le initWithCoder qui vient remplacer initWithFrame) et encore moins dataRepresentationOfType et loadDataRepresentation...
J'ai regardé le tutoriel "Echecs" qui traite de l'enregistrement des parties, et qui est une "Cocoa Application" mais cela n'utilise pas l'archivage mais une autre méthode d'enregistrement, d'après ce que j'ai compris. Quelles sont donc les différences ? Peut-on utiliser l'archivage avec un application qui n'est pas "Document Based" ?
Pardon pour toutes ces questions de newbie, et merci de l'accueil !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Dans les cas simples on s'en passe facilement. Dans le tuto Echecs j'enrgistre un NSArray, qui est accepté directement par la methode writeToFile, donc pas besoin de NSCoder.
J'ai donc essayé d'utiliser la méthode du tutoriel dans mon application. Malheureusement, il me renvoie une erreur lorsque j'essaie de faire "Fichier/Enregistrer sous" : "Can't save file '/Users/jean-baptistebournisien/Desktop/Sans titre.dessin': No such file or directory"
Forcément que le fichier n'existe pas, puisque je veux le créer...
Voici ma méthode savePanelDidEnd :
Une idée ?
D'avance merci, désolé pour ces questions de newbie !!!
Du coup l'erreur que tu as "No such file or directory" ne correspondrait pas du tout à l'erreur que tu as effectivement, ce qui voudrait dire que le problème ne viens pas du tout de là .
Enfin c'est une hypothèse parce qu'en fait je ne sais pas où tu pourrais récupérer le code d'erreur sinon, mais bon vu que perso j'utilise très peu errno (faut dire que souvent je n'affiche les messages d'erreurs que lorsque j'ai un NSError à disposition )
Vérifie que ton NSDictionary ne contient bien que des types d'objets qui peuvent être écrits dans un fichier plist : NSData, NSDate, NSNumber, NSString, NSArray, ou NSDictionary.
Si tu as d'autres types que ceux-là dans ton tabTraits, il faut les convertir (en pasasnt par ds NSCoder) dans un type supporté par les fichiers plist.
Oh, et PS : Pour quelqu'un qui se qualifie de "newbie", je trouve que tu te débrouilles plutôt bien Et en plus tu as le mérite de chercher avant de poser la question, du moins il me semble, donc tu n'as pas à t'excuser, un forum est fait pour ça
C'est embêtant si le code d'erreur ne veut rien dire... ???
En ce qui concerne ma newbizitude il est vrai que ce n'est pas la première fois que je m'essaie à la programmation (j'ai même des diplômes pour cela) mais je trouve que le développement en Cocoa est tout de même assez différent des différents langages que j'ai pu essayer jusqu'à maintenant (Delphi, PHP, VB, Java, C/C++). C'est pour cela que j'ai l'impression de patauger un peu par moment. Faut dire que cela fait aussi un bout de temps que je n'avais pas entrepris d'apprendre un langage de programmation par moi-même. Enfin bref...
Bon alors oui pardon en effet c'est un NSArray et pas un NSDictionary que tu essayes d'enregistrer, mais ça ne change rien au problème : est-ce que ton NSArray contient bien que des objets enregistrables dans un plist, et ceci dans toutes les "profondeurs" de ton NSArray ?
Par exemple si tu as un NSArray de NSDictionnary et que tes NSDictionary contiennent par exemple entre autres des NSColor, ça n'ira pas car NSColor n'est pas enregistrable dans un plist... qu'ils soient directement à la "racine" de ton NSArray ou dans un sous-élément, ou sous-sous-...-sous-élément
J'avais pas capté (c'était pourtant évident) qu'il fallait que les éléments d'un NSArray soit également d'un type encodable.
Merci 1000 fois !
Un truc pratique pour stocker des NSPoint dans une NSString est d'utiliser NSPointFromString et NSStringFromPoint. Il n'y a plus qu'à faire un NSArray de ces strings pour les enregistrer.
Plus généralement, pour stocker plusieurs chose différentes dans une même string, par exemple un entier un float et un NSPoint, il est pratique d'utiliser componentsSeparatedByString: en conjonction avec intValue, floatValue, et NSPointFromString
J'avais pas pensé à NSPointFromString et NSStringFromPoint pour l'archivage (je les utilise plutôt pour l'affichage en général), mais c'est vrai que c'est pas bête
Par contre pour les objets plus complexes, qui contiennent plusieurs composantes etc, plutôt que componentsSeparatedByString moi je préfère faire un NSDictionary, pas toi ?
Quitte à créer des NSNumber pour encapsuler les int, float, ... puisque c'est fait pour.
Je trouve qu'un dictionnaire est plus approprié pour décrire des données et donc les archiver
Enfin bon y'a pas de méthode meilleure qu'une autre, donc c'est comme tu le sens JB.
Et puis si y'a que des NSPoints, la méthode de WIMP est aussi simple. C'est plus quand t'as des "gros" objets que le dico devient utile.
Disons que c'est "culturel": on n'aime pas trop changer ses habitudes, et il faut apprendre à utiliser NSCoder, NSArchiver, etc...
Pour répondre à Aligator:
Jusqu'à présent je n'ai utilisé NSDictionary que pour enregistrer des préférences.
Je trouve NSDictionary assez lourd à manier, et je ne vois pas très bien la nécessité des paires clef-valeur pour enregistrer des données.
Puisque de toutes façons le problème se ramène à traduire ces données en NSData, j'essaie de placer mes données dans des structures C standard que je liste dans des NSArray, comme dans mon tuto Echecs.
La méthode componentsSeparatedByString revient aussi à créer une structure.
Finalement je pense qu'il n'y a pas de methode d'archivage idéale, à chacun de trouver celle qui lui convient le mieux.
Enfin, je crois que pour organiser les données l'essentiel à prendre en compte est aussi et surtout l'efficacité du code qui les manipule, en termes de simplicité et de vitesse d'exécution.
Si tu t'intéresses un peu au NSCoder, tu verras que ce n'est pas plus dur que de stocker des données dans une string. Là où tu fais [anArray addObject:NSStringFromPoint(aPoint)] avec un coder "normal", tu fais simplement [coder encodePoint:aPoint]. En procédant de la sorte, tu peux mettre des objets dans un tableau et sauver le tableau avec writeToFile:atomically: directement, sans n'avoir aucun travail de conversion à faire. Je ne parle là que de l'écriture, mais la lecture est tout aussi simple.
Sinon effectivement, le dico n'est pas la solution la plus adéquate (mais c'est celle qui offre le plus de souplesse), mais par rapport à la solution de la string, je ne vois vraiment pas pourquoi tu ne veux pas utiliser un tableau, tu n'auras pas plus de contraintes (=la contrainte d'ordre), mais par contre tu peux stocker des objets bien plus complexes (conformes à NSCoding).
Pour ma part c'est "profitons de ce que les autres ont fait".