L'aventure Mac App Store
Ce ne fût pas sans embûches, mais ça y est, PLISTBlender est disponible sur le Mac App Store. Récit et anecdotes.
Départ
J'avais déjà réalisé une app en Swift, ADNPing, mais sa nature ne permettait pas de la placer sur l'App Store. Et en fait je ne m'étais même pas vraiment posé la question. Je l'ai mise à disposition de la petite cinquantaine d'utilisateurs potentiels, et elle a immédiatement trouvé son public ; ça me suffisait.
J'ai ensuite eu besoin, pour un projet qui n'a pas abouti, de consulter le contenu de fichiers plist se trouvant dans le dossier Library
de mon installation de Mac OS X.
Malheureusement pour moi, la plupart de ces fichiers sont dorénavant des binaires, alors que dans de précédentes versions d'OS X ils étaient en XML.
Donc je ne pouvais pas les consulter ou les convertir sans une application compatible.
Evidemment on peut les modifier avec Xcode, mais pour consulter leur contenu rapidement ou préparer des exports dans d'autres formats c'est vraiment pas idéal du tout.
Il y a aussi plutil
, l'outil en ligne de commande fourni par Apple, mais -et pourtant je suis un amoureux du terminal- ce n'était pas pratique non plus.
J'ai ensuite cherché sur l'App store avec les mots-clés qui vont bien, et suis tombé sur quelques malheureuses appounettes pas très excitantes. J'ai acheté pour 5€ celle qui me paraissait la meilleure.
Je m'en suis servi deux minutes, puis j'ai murmuré “crétins”.
J'ai donc décidé, gros naïf, de faire moi-même une petite application utilitaire qui serait capable de lire tous les formats de plist et de les exporter également dans n'importe quel format compatible, sans erreur.
Ben oui, ça allait me prendre quoi, une petite semaine ? Trois boutons, une fenêtre avec du texte, et hop.
Presque.
Vrai projet
Mais après quelques jours une évidence s'imposait : soit j'en restait là, avec une application moche et ayant peu de fonctions, mais qui me permettait d'accomplir cette fucking tâche pour le projet parallèle, inspecter les fichiers de préférences dans la bibliothèque…
…soit je la transformais en vraie application, jolie, pleine de fonctions utiles, solide et sans bug.
Ce jour-là, quand j'ai réalisé ça, j'ai pris une très longue réflexion d'environ une seconde puis j'ai décidé d'en faire une vraie app.
J'ai donc commencé par tout casser : l'architecture de la version alpha était plutôt bancale, et supporterait mal d'évoluer comme je le désirais.
J'en ai profité pour réfléchir un peu, aidé comme toujours par mindmup.com pour établir des plans d'action.
L'application aura donc une seule fenêtre, mais trois tabs, chacune montrant une des trois représentations possibles du contenu du fichier binaire : objets Cocoa, JSON et XML.
Et bien sûr un bouton export, des menus, ah tiens et aussi elle va supporter le drag and drop, et puis il faudrait pouvoir changer de polices et de couleurs pour le texte, et puis…
Voilà. C'est comme ça qu'on met un pied, puis deux, puis y'a tout qui suit. ;)
Outils
J'avais deux options pour convertir les fichiers plist à partir de Swift : utiliser les bibliothèques Cocoa, ou faire appel de manière invisible à plutil
.
Et en fait j'utilise les deux.
Je fais appel à plutil
pour valider des fichiers qui pourraient contenir des erreurs, et pour exporter les fichiers dans les formats compatibles.
En effet, faire la validation du JSON par exemple en Swift n'était pas pratique car la bibliothèque d'Apple était elle en Objective-C et balançait d'horribles exceptions à chaque erreur. Pas pratique.
Et je manipule les bibliothèques Cocoa pour ouvrir les fichiers validés et pour faire subir les transformations aux données à afficher dans la fenêtre (JSON vers XML par exemple).
Pas besoin de frameworks externes ou d'importer quoi que ce soit, mais j'utilise tout de même Async en surcouche à dispatch_queue
pour avoir moins de code à taper pour gérer le multi-tâche.
Multi-tâche
En effet, la grande difficulté quand on crée une application OS X, c'est de gérer les différents process qui se déroulent en même temps dans l'application.
Si vous ne séparez pas certaines opérations gourmandes en calcul du “main thread”, c'est-à-dire de la couche où se déroule la partie graphique de l'application, alors l'utilisateur va voir apparaître la beachball of death et devoir attendre que l'app aie fini de bosser pour reprendre la main. Euh, on est en quelle année, là ? Donc c'est inacceptable, donc il faut lancer les calculs en “background” (arrière-plan) et en parallèle, et rafraîchir l'interface avec les nouvelles données dans le “main thread”.
Pas évident, surtout qu'Apple pousse très fortement à respecter le concept d'architecture MVC (modèle-vue-controlleur) et que si on n'a pas l'habitude… c'est l'enfer.
Il faut éviter les race conditions, trouver des systèmes pour que le main thread soit toujours libre, etc. Heureusement Swift aide beaucoup car pousse à réfléchir en mode “fonctionnel” (contrairement à “objet” ou “impératif”), avec notamment des constantes et objets immutables, pour éviter justement que les uns marchent sur les pieds des autres.
Mais comme pour tout, une fois que l'on a acquis les “grandes idées”, avec la pratique vient l'expérience, et on finit par penser presque naturellement en termes de fonctions, de controlleurs, de modèles, de messages inter process, etc.
Evidemment pour mes premières tentatives je me suis fait avoir comme un bleu et j'ai bien dû commetre au moins une fois chaque atrocité possible. ;)
J'ai eu aussi du mal, au début, à suivre les règles du sandboxing, qui certes garantissent une certaine sécurtité à l'éco-système Apple, mais placent sur les épaules du développeur de sévères contraintes.
Mais finalement, après chaque “non mais LOL !” ou “what the fffffck” vient le soulagement d'avoir compris son erreur, et la joie de recommencer sur de bonnes bases.
Aujourd'hui, PLISTBlender est complètement MVC, sandboxé, respecte les règles implicites dictées par Apple et sait faire plein de choses en même temps… même s'il n'en a pas vraiment besoin.
Interface
Je suis un gros naze en design. Ou plutôt, je sais voir, je sais discerner et analyser, mais je ne sais pas produire. Je n'ai jamais su dessiner correctement, et j'ai un défaut de vision qui donne une dimension toute personnelle au concept de “aligné” et “droit”…
Donc j'ai fait appel à un ami très cher, qui m'a rapidement présenté une superbe maquette, que j'ai utilisée comme base et faite évoluer en fonction des besoins et contraintes.
App Store
Et me voilà enfin, après un gros mois très intense, avec une app que je trouve fort belle et ma foi prête à aller rencontrer son public (de niche, certes).
Sauf que attends, mec, pas tout de suite, trop facile. ;)
Il faut d'abord s'ouvrir un compte pour l'App Store. Ca veut dire toutes les déclarations de banque, d'imposition, etc.
Il faut ensuite créer un site -ou au moins une landing page- pour l'application, c'est explicitement demandé par Apple.
Créer un set d'icones complet à toutes les résolutions supportées par Mac OS X.
Remplir toutes les méta-informations de l'application, les mots-clés, le résumé, les captures d'écran, etc.
Il faut finalement générer une version spéciale avec Xcode, la faire valider, l'uploader dans son compte “iTunes Connect”, préparer cette version et la relier aux méta-données, puis finalement, oui, on peut la soumettre à Apple pour qu'ils décident s'ils sont d'accord pour la faire apparaître sur la Mac App Store. Wow. :)
Crash
Bon, nous voilà prêts, je compile, je valide, j'upload, etc, je soumets : click ! Il n'y a plus qu'à attendre.
Sept jours plus tard, je reçois une missive d'Apple : “Application rejected”.
Allons bon… “Application that crash will be rejected.” Bah oui ça je sais que vous n'en voulez pas des apps qui crashent, ça tombe bien la mienne elle crashe pas. “Your application crashed when launched and couldn’t be tested.”
WTF. Bon, j'inspecte le crash log… Jamais vu une erreur pareille. C'est comme si un morceau de code était manquant. Evidemment rien ne marche dans ces conditions, et ça crashe.
A force d'inspecter, je découvre que… je n'avais pas envoyé le bon binaire à Apple. :/
Non mais quelle andouille, vraiment. Bon, je compile à nouveau, je vérifie que j'envoie le bon fichier… et j'attends.
Une semaine de plus.
Release
Puis un email qui ressemble à l'autre arrive… “oh non”… mais surprise ! La ressemblance était trompeuse. Le titre de celui-ci était beaucoup plus agréable : “Your app has been approved and will be soon on the App Store”.
Il a fallu attendre encore quelques heures que les automatismes chez Apple fassent leur truc (réplication de l'app dans tous les App Store, etc) puis voilà, c'était fait.
PLISTBlender, l'utilitaire pour visualiser et convertir les fichiers de préférences, est lâché dans la nature.
Et son papa est très heureux. :)