[Astuce] implémenter un protocole par autocomplétion
AliGator
Membre, Modérateur
Hello les gens,
Je recherche une astuce (je me demande si elle existe pas déjà , et sinon comment on pourrait faire pour créer un plugin ou un AppleScript ou une TextMacro pour ça) pour rapidement implémenter un protocole dans mon code.
Je m'explique : à chaque fois qu'on développe une classe et que l'on veut qu'elle réponde à un protocole (ce qui est d'ailleurs encore plus fréquent avec l'iPhone SDK où par exemple tous les delegates des classes CocoaTouch sont de type "id<protocol>"), il faut aller rechercher dans la doc la signature des méthodes du protocole et les copier/coller dans notre code pour les implémenter. Ou les taper à la main et jouer de l'autocomplétion, encore faut-il se rappeler de leur nom même si certainesont un nom explicite, il faut éviter d'en oublier...
Jusque-là le meilleur moyen que j'ai trouvé pour coller rapidement toutes les méthodes à implémenter pour répondre à un protocole donné, c'est de taper (ou trouver qqpart dans mon code) le nom du protocole à implémenter, de faire pomme-clic sur ce nom pour arriver à sa définition dans le header Apple (ou pas) correspondant, et copier-coller toutes les méthodes dans mon code... puis enlever les lignes en surplus (commentaires, mention "@optional", ...), et enfin remplacer tous les ";" par des "{" et "}" à la main...
Mais je me dis que si on pouvais automatiser ça, ça serait quand même vachement sympa ! Genre on tape "UITableViewDelegate"+<esc> dans le code et hop ça nous propose d'insérer automatiquement dans notre ".m" toutes les méthodes de ce protocole, prêtes à être implémentées... quitte à ce que ça indique en commentaire celles qui sont optionnelles et qu'on les jarte à la main si on n'en a pas besoin... ou mieux que ça nous propose d'insérer automatiquement soit que les méthodes obligatoires du protocole, soit toutes les méthodes, optionnelles comprises...
Des idées pour mettre cette astuce en place ?
Bien sûr y'a une solution envisageable, ça serait de rentrer tous les protocoles connus dans un fichier de TextMacros, j'ai bien pensé le faire mais (1) un peu rébarbatif à rentrer, faudrait les rentrer tous sans en oublier un seul et (2) ça n'est pas évolutif avec la doc, l'idéal serait d'aller chercher les infos directement en parsant les headers, non ?
Je recherche une astuce (je me demande si elle existe pas déjà , et sinon comment on pourrait faire pour créer un plugin ou un AppleScript ou une TextMacro pour ça) pour rapidement implémenter un protocole dans mon code.
Je m'explique : à chaque fois qu'on développe une classe et que l'on veut qu'elle réponde à un protocole (ce qui est d'ailleurs encore plus fréquent avec l'iPhone SDK où par exemple tous les delegates des classes CocoaTouch sont de type "id<protocol>"), il faut aller rechercher dans la doc la signature des méthodes du protocole et les copier/coller dans notre code pour les implémenter. Ou les taper à la main et jouer de l'autocomplétion, encore faut-il se rappeler de leur nom même si certainesont un nom explicite, il faut éviter d'en oublier...
Jusque-là le meilleur moyen que j'ai trouvé pour coller rapidement toutes les méthodes à implémenter pour répondre à un protocole donné, c'est de taper (ou trouver qqpart dans mon code) le nom du protocole à implémenter, de faire pomme-clic sur ce nom pour arriver à sa définition dans le header Apple (ou pas) correspondant, et copier-coller toutes les méthodes dans mon code... puis enlever les lignes en surplus (commentaires, mention "@optional", ...), et enfin remplacer tous les ";" par des "{" et "}" à la main...
Mais je me dis que si on pouvais automatiser ça, ça serait quand même vachement sympa ! Genre on tape "UITableViewDelegate"+<esc> dans le code et hop ça nous propose d'insérer automatiquement dans notre ".m" toutes les méthodes de ce protocole, prêtes à être implémentées... quitte à ce que ça indique en commentaire celles qui sont optionnelles et qu'on les jarte à la main si on n'en a pas besoin... ou mieux que ça nous propose d'insérer automatiquement soit que les méthodes obligatoires du protocole, soit toutes les méthodes, optionnelles comprises...
Des idées pour mettre cette astuce en place ?
Bien sûr y'a une solution envisageable, ça serait de rentrer tous les protocoles connus dans un fichier de TextMacros, j'ai bien pensé le faire mais (1) un peu rébarbatif à rentrer, faudrait les rentrer tous sans en oublier un seul et (2) ça n'est pas évolutif avec la doc, l'idéal serait d'aller chercher les infos directement en parsant les headers, non ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Un raccourci est d'utiliser le Research Assistant : tu écris UITableViewDelegate n'importe où, et le Research Assistant te mets le lieu où se trouve le .h définissant le protocole. Tu cliques sur ce .h et tu te retrouves exactement sur la définition dudit protocole. Il ne reste plus qu'à copier-coller ...
Automatiser cela par un script ?
[EDIT] Hum ... pas si simple, cela marche, mais moins bien pour le NSOutlineViewDatasource protocole
Ben c'est bien l'idée qui m'intéresse...
Après avoir galéré pas mal, j'ai fini par aboutir à un script sed pour parser tous les .h d'un répertoire, rechercher les blocs @protocol...@end et les transformer en TextMacros... J'en ai ch*é avec quelques cas particuliers, mais j'ai fini par y arriver !
Installation :
Cela va alors vous créer un fichier [tt]Protocols.xctxtmacro[/tt] (ou le nom que vous avez demandé le cas échéant) dans [tt]/Users/olivier/Library/Application Support/Developer/Shared/Xcode/Specifications[/tt]. Relancez Xcode et vous devriez avoir un menu "Protocols implementation" (ou le nom que vous lui avez demandé le cas échéant)
Utilisation
Comme j'ai, en tout logique, associé comme "CompletionPrefix" pour chaque protocole le nom dudit protocole, il vous suffit, une fois le fichier de TextMacros créé, de lancer Xcode et vous placer dans un de vos fichier .m, entre un bloc @implementation et @end là où insérer les méthodes, puis taper le nom d'un protocole et demander l'autocomplétion.
Ainsi, si vous tapez "UITableViewDe"+<esc> cela va vous proposer "UITableViewDelegate implementation" et si vous validez, cela va insérer toutes les méthodes @required du protocole ainsi que les méthodes @optional entourées de /*...*/ qu'il vous suffit de décommenter si vous souhaitez les implémenter.
Phase de beta-tests
Perso je n'ai testé la création de ces TextMacros par mon script qu'avec le Framework iPhoneSimulator 2.2.1 et ça a l'air de marcher... mais j'ai pas vérifié qu'il n'avait pas oublié de @protocol ni qu'il avait correctement parsé les fichiers.
Merci si vous testez ce script et utilisez les TextMacros de me faire des retours pour me spécifier si tout marche bien ou s'il manque des choses, etc...
Et puis si tout marche bien je le posterai dans "Trucs & Astuces" du site
PS : Si y'en a qui veulent des explications sur le code de mon script sed, qu'ils n'hésitent pas, maintenant je commence à bien maà®triser du coup :P
[EDIT] : Fichier joint supprimé, nouvelle version corrigeant des bugs dans le post suivant
--> Vous crée le fichier de TextMacros contenant tous les @protocols listés dans le Framework (ici iPhone221 mais choisissez un autre dossier selon vos désirs)
--> Vous n'avez plus qu'à taper dans votre code le nom du protocole puis taper la touche d'autocomplétion (<esc> chez moi) pour qu'il vous propose de vous insérer toutes les méthodes @required (+ les @opional commentées entre /*...*/) du protocole dans votre .m !
Cette nouvelle version corrige juste des bugs dans le script sed qui faisaient que certaines méthodes étaient oubliées ou d'autres vues comme @optional au lieu de @required (ou vice-versa) si le @optional était juste après une méthode ignorée...
Je ne sais pas trop d'où ça peut venir, ni te donner plus d'info, je vais essayer de voir.
[edit] J'ai trouver, c'est parce que je n'avais pas de répertoire Specifications dans : [tt]/Users/olivier/Library/Application Support/Developer/Shared/Xcode/[/tt]
Bon je modifierai mon script pour qu'il crée le répertoire si inexistant, en plus c'est pas méchant. Bonne remarque.
Sinon rassure-moi, tu t'appelles bien Olivier comme moi ? Donc ce n'est qu'un hasard si ton répertoire maison ($HOME) s'appelle aussi "olivier" exactement comme moi hein ? Et non pas un relicat de mon nom de répertoire maison que j'aurais laissé en dur dans le script, risquant de faire qu'il ne fonctionne pas chez ceux dont le répertoire maison aurait un autre nom ? :P
Merci de ton test en tout cas.
PS : J'ai modifié l'exemple dans mon post plus haut, dans le chemin du dossier de Frameworks à parser, j'avais omis de mentionner "/Developer" donc ça n'aurait produit qqch que si on était déjà dans /Developer...
Par contre je ne me rappel pas avoir eu une erreur de répertoire, c'est pour ça que je n'ai pas compris pourquoi je n'avais pas de menu. Je suis aller voir avec un cd ce qu'il y avais dedans et là j'ai vu que le répertoire n'existait pas.
Voilà , en tout cas merci pour ce script, si j'en ai pas encore eu l'utilité, je pressent que ça ne va pas tarder ^^
Voilà je pense avoir fait le tour.
Pour ma part j'utilise mon script en l'appelant tout simplement par "[tt]./protocols2textmacro.sh -sdk[/tt]" et comme les valeurs par défaut me vont je n'ai plus qu'à valider (en mm temps c'est normal c'est moi qui les ai définies )
[EDIT]
Désolé j'ai posté un peu vite et n'avais pas testé avec les SDK de MacOSX (seulement iPhone). La version 1.5.2 est du coup disponible dans le post suivant (j'enlève le fichier joint v1.5 de ce post pour éviter les profusions de versions).
(étonnamment, cela arrive, en particulier dans le header NSMatrix.h du SDK 10.6, définissant un @protocol totalement vide pour le coup, mais sans doute en prévision de l'introduction de ce @protocol dans une future version ?)
Ces erreurs empêchaient le fichier xctxtmacro généré par le SDK de MacOSX 10.6 de se charger dans Xcode (le @protocol et @end sur la même ligne faisait foirer mon parsing sed, le mauvais encodage du texte faisait foirer le parsing du xctxtmacro par Xcode)
Vous pouvez donc maintenant aussi utiliser cette version du script pour parser les @protocols du SDK 10.6 !