Categories
Non classé

Backdrop

Je viens de découvrir Backdrop. Cette application sert à masquer le Bureau et ses icônes en les remplaçant par un autre fond. Ceci s’avère bien utile pour préparer des copies d’écran de votre application avant sa publication sur le Mac App Store.

Essayez-là, elle est bien faite et gratuite.

Categories
Non classé

Quelques nouvelles

Voilà fort longtemps que je n’ai rien écrit sur ce blog. Ces derniers mois en fait furent très occupés.

Tout d’abord, je donne dorénavant des formations au développement sous iOS pour le compte de la société Mediabox. Tout se passe bien: les gens de Mediabox sont sympas, les locaux sont nickels et en plus, on mange bien à midi au bistrot du coin. Les premiers stagiaires que j’ai eu étaient motivés et nous sommes allés quasiment au bout du programme de la formation, finalement très chargée (surtout après le repas au bistrot, si on a pris une entrée). Si ça vous intéresse, la prochaine session est déjà programmée du 24 au 28 octobre.

J’ai travaillé sur la version iPad de PortraiMatic; non le projet n’est pas abandonné, en fait, le logiciel tourne déjà plutôt correctement, il me reste un travail d’optimisation (mémoire et vitesse) et de finition avant de le proposer à mes bêtas testeurs en vacances.

En parlant de vacances, les miennes sont terminées. Peupeul a eu l’idée de lâcher son nouveau félin “Lion” (Mac OS 10.7) pile au milieu de mon séjour, si bien que je le découvre seulement aujourd’hui. Et évidemment, PortraiMatic est incompatible, alors que la transition de 10.5 à 10.6 s’était faite sans douleur. (D’accord, j’admets que c’est de ma faute, parce que je n’ai pas pris le temps de tester les bêtas de Lion, mais quand même, je me demande ce qu’ils ont changé pour que ça foire autant).

Pour finir, je re-découvre Twitter. Vous pouvez dorénavant suivre mes aventures sous @renaudpradenc.

Categories
Non classé

Les Français restent des écoliers

Ce fait est troublant: affichez deux champs de texte, le premier pour saisir le prénom, le second le nom de famille. Vous constaterez que la moitié des sujets français saisit son nom de famille dans le champ Prénom, et son prénom dans le champ Nom. Ceci est mon expérience d’un an et demi de vente de PortraiMatic.

Le taux d’inversion est similaire chez les Belges francophones, moindre chez les Suisses francophones, et quasiment nul pour les autres. Je suppute que nous autres français avons l’esprit formaté par nos années d’école où le nom précède toujours le prénom et la foule de documents administratifs qui suivent cette règle pour la plupart.

Categories
Non classé

PortraiMatic iPad (2): Reprendre le code de la version Mac ?

C’est décidé, je vais convertir PortraiMatic du Mac à l’iPad. Mais par où commencer ?

Faut-il reprendre le code de la version Mac ?

Il s’agit d’une question économique, à savoir: sachant que les bibliothèques de développement Mac et iOS possèdent de nombreuses similitudes, peut-on partager les fichiers sources entre les deux plateformes ? Après tout, le langage de programmation est le même, et Cocoa Touch est une adaptation de Cocoa Mac. Et si la réponse est positive, est-ce que la lourdeur structurelle (mise en place sous Xcode) n’anéantis pas le bénéfice de cette réutilisation?

Le gros du code concerne l’IHM

L’Interface Homme-Machine représente une grosse proportion dans PortraiMatic. Or, il s’agit probablement d’une des plus grosses différences entre Mac OS et iOS. D’un côté, nous utilisons App Kit, de l’autre UIKit. Il ne s’agit pas d’une simple adaptation: les ingés d’Apple l’ont repensé pour l’utilisation avec un écran tactile et l’ont grandement modernisé.

PM_ReframeView

Par exemple, je sais d’avance que je vais devoir reprogrammer entièrement la vue qui sert à recadrer les portraits. Or, il s’agit de la classe la plus complexe de PortraiMatic Mac.

Pas de bindings

Les Bindings sont une des technologies les plus utiles, mais également les plus complexes qui existe sur Cocoa Mac. Cette technologie synchronise l’état des vues (ce qui apparaît à l’écran) et l’état interne (couche ‘métier’). PortraiMatic en fait grand usage, entre autres parce qu’elle réduit les dépendances entre classes, et donc la complexité de l’architecture. Pour des raisons de performances, je pense, cette technologie n’a pas (encore) trouvé son chemin dans Cocoa Touch. Il existe des alternatives, mais cela signifie à nouveau que de grand pans du code ne peuvent pas être réutilisés.

Pas de Core Image

Core Image est ma technologie préférée dans Mac OS X. Elle permet d’appliquer des effets sur les images voire de générer des images. C’est une technologie à la fois performante, facile à utiliser et extensible. Malheureusement, elle n’a pas encore été portée sous iOS, même si je ne doute pas que cela sera fait prochainement. En conséquence, j’ai décidé, dans un premier temps, de ne pas inclure de fonctions de corrections de couleurs dans la version iPad. Non, pas que ceci me poserait de problème particulier (la programmation graphique est ma spécialité), mais je veux publier l’application rapidement.

Gestion des fichiers

La gestion des fichiers dans PortraiMatic est à la fois un motif de satisfaction — parce qu’elle est maintenant bien au point — et une inquiétude à chaque nouvelle version pour s’assurer de la compatibilité avec les versions précédentes. Elle présente quelques détails malins. Tout d’abord, la “galerie” est un bundle, c’est à dire un dossier qui apparaît comme un fichier sous Finder. On peut l’ouvrir sous Finder, par un clic droit > Afficher le contenu du paquet, et constater que chaque portrait possède son dossier:

PM_BundleGalerie

Chaque dossier comporte l’image utilisée par le portrait et un fichier Portrait.plist qui décrit les paramètres du portrait (recadrage, correction des couleurs). Cette organisation s’est révélée pratique en cas de problème (on peut mettre un dossier à la corbeille), plus simple à déboguer (on voit immédiatement si les données ont été enregistrées). Elle a aussi permis de mettre en œuvre facilement la fusion des galeries de deux utilisateurs. Cependant, je vais passer à Core Data pour enregistrer les données.

Core Data permet de décrire le modèle (la partie “métier”) de l’application de façon graphique et de stocker les informations dans une base de données SQLite de façon transparente. J’en attends des simplifications de l’architecture et une baisse de volume du code source. Par ailleurs, elle devrait régler mes soucis de migration d’une version à l’autre, en m’obligeant à décrire précisément les évolutions de chaque version.

À l’heure du choix

Finalement, je constate que peu de code peut être repris; si nécessaire, je dispose toujours de la possibilité de copier-coller du code. Je n’ai franchement pas envie de m’engager dans des problèmes d’inclusions de fichier d’un projet Xcode à l’autre. Il me semble donc plus opportun de ne pas partager de fichiers entre les versions Mac et iPad, et de créer un projet Xcode tout neuf.

Categories
Non classé

PortraiMatic iPad (1): Objectif du projet

Je me suis décidé à convertir mon logiciel PortraiMatic du Mac à l’iPad. Je débute donc une série d’articles qui vous permettra de suivre l’avancement de l’application, mais surtout qui vous expliquera mes choix et les problèmes que j’ai rencontré.

L’objectif du projet

Quand développer un logiciel est un loisir, il importe finalement peu que ce projet ait un avenir; on le fait avant tout pour le plaisir, pour le challenge intellectuel. À l’inverse, dans le cadre d’une société, chaque choix doit être motivé. Aussi doit on avoir des objectifs avant d’investir son temps dans l’écriture d’une application. L’objectif le plus courant est de gagner de l’argent, mais peut être de se former, de tester la faisabilité technique d’une idée, ou de promouvoir la société.

Version iPhone

On m’a demandé à de nombreuses reprises pourquoi PortraiMatic n’existait pas sur iPhone. La réponse est très simple: ce serait un mauvais investissement. Il existe déjà un palanquée d’application à 0,79 € pour produire des planches de photos d’identité. Même si je concevais le meilleur programme du genre — ce qui est probable — elle ne pourrait guère être vendue plus d’1,59 €. Rappelons que sur 1,59 €, la société ne toucherait que (1,59 – 15% de TVA – 30% de commission d’Apple) = 0,95 €. Rappelons que pour me verser un salaire de 1500 € nets/mois, cela coûterait à la société Céroce à peu près le double pour payer les charges sociales, soit 3000 €. Rappelons que les sociétés sont soumises à divers impôts et ont des frais, ne serait-ce qu’un loyer, des abonnements au téléphone et à Internet, d’importants frais de transport, acheter des Mac ou iPad ou une imprimante, et toutes les fournitures qui vont avec, de la documentation, un comptable, etc. Eh bien on arrive vite à 5000 €/mois. Notez que je ne fais pas cet inventaire pour me plaindre de “toutes ces charges qui plombent les entreprises”, comme on dit au MEDEF, mais pour effectuer un calcul réaliste.

Imaginons que je passe trois semaines sur le développement de la version iPhone (ce qui est optimiste), il faudrait qu’elle rapporte 3/4 de 5 000 € soit 3 750 €. Le premier jet serait donc rentable avec 3 948 ventes. Or, si vous croyez que c’est facilement atteignable, vous vous trompez lourdement. L’application serait noyée au milieu de 350 000 autres ! Si bien qu’il faudrait un plan marketing pour y parvenir, qui prend du temps et a un coût. C’est bien simple, si la promotion prenait trois semaines, il faudrait vendre deux fois plus d’exemplaires. Bref, j’ai préféré ne pas investir mon précieux temps sur ce marché.

Version iPad

Pourquoi une version iPad alors ? Certes la concurrence y est moindre (seulement 65 000 applications) et je pourrais pratiquer un prix de vente plus correct, autour de 5 €. Mais à vrai dire, je doute fortement que le coût du développement sera couvert par les ventes. L’objectif est ailleurs: démontrer mon savoir faire sur cette plateforme. Comme tout prestataire amené à démarcher des clients, il me faut les convaincre de ma capacité à réaliser un projet complexe. Cette version iPad sera mon ambassadrice. Quand l’iPad fut présenté l’année dernière, je me suis dit que c’était la machine idéale pour PortraiMatic. C’est encore plus vrai pour l’iPad 2 et ses caméras intégrées.

Categories
Non classé

BeMyApp 4

Me voilà bien en retard pour parler de ma participation au quatrième BeMyApp qui eut lieu le week-end du 4 février. Rappelons qu’il s’agit d’un concours consistant à mettre au point une application mobile en un week-end. J’avais déjà participé aux deux premières éditions consacrées à l’iPhone. Vous pourrez lire à leur propos ici et .

À chaque édition, nos deux compères, John et Cyril, tentent de nouvelles choses. Certaines fonctionnèrent bien. Ainsi, avaient-ils décidé que nous livrerions l’application et son source le dimanche avant 18 heures, avec deux objectifs. L’un étant de permettre aux 50 bêta-testeurs, pré-inscrits depuis un mois, d’installer les applications sur leurs iPhone et les tester, et l’autre de transmettre le code source à Guillaume Cerquant, chargé de décerner le prix du meilleur code. Cette organisation fut pertinente, puisqu’à 18 heures, nous autres développeurs fûmes libérés du travail, pûmes enfin nous restaurer et préparer la présentation avec le porteur de projet.

Autre succès, j’ai constaté que les bêta testeurs ont bien joué le jeu et donné leurs avis. L’engouement pour notre application est très encourageant pour la suite.

Autre nouveauté, cette édition fut la première à être nationale; ne se déroulant pas qu’à Paris, mais aussi à Lyon et Marseille. Le succès de cette initiative est mitigé. D’un côté, les équipes provinciales ont bien travaillé, de l’autre, les retransmissions vidéos entre les trois sites furent un échec à cause du LiveStream qui créait un décalage de près d’une minute, et ne permit pas aux spectateurs de vivre l’événement. Cette infrastructure fit perdre trois heures à tout le monde le samedi, et allongea énormément la délibération du dimanche. Par ailleurs, les marseillais ne parvinrent pas à faire fonctionner le LiveStream chez eux.

Parlons un peu des idées soumises au public. À vrai dire, dans leur ensemble, elles ne m’ont guère emballé. Peut-être qu’avec trois participations, je deviens blasé ! Heureusement, l’un des projets à été repêché au dernier moment. Il s’agit d’iKado. Je suis heureux de la manière dont nous avons travaillé durant ce week-end. Je me suis particulièrement bien entendu avec toute l’équipe, Mathieu, le porteur de projet qui devint graphiste pour la circonstance, Anthony et François-Julien, les deux autres développeurs venus de Marseille, et passés par Supinfo. Aussi, une rivalité sympathique se créa entre les trois écoles d’ingénieur représentées.

De gauche à droite: François-Julien, Anthony, moi et Mathieu.
De gauche à droite: François-Julien, Anthony, moi et Mathieu.

Nous avons vraiment travaillé très dur. Le projet nécessita la mise en place d’un service web, aussi m’y suis-je collé parce que j’étais le plus expérimenté, malgré mon peu d’expérience sur les technologies web. J’ai donc laissé François-Julien et Anthony travailler sur l’application iPhone, quasiment autonomes. Je ne suis intervenu que pour déboguer le programme de temps en temps, et leur expliquer quelques concepts. Leur code était plutôt propre, mais le dimanche matin, j’ai travaillé deux heures pour le réarranger un peu.

Malheureusement, je n’ai pas avancé aussi vite que voulu sur la partie web, ce qui nous a obligé à réduire nos ambitions pour la présentation du dimanche. L’application finale fut quand même fonctionnelle, assez pour expliquer clairement l’intérêt au jury.

Pour finir, sachez que parmi les trois prix décernés, nous avons reçu le prix Parrot, du meilleur code, qui nous récompensa chacun d’un AR Drone ! Je n’ai pas encore eu beaucoup de temps pour m’exercer au pilotage, et je ne suis pour l’instant pas très brillant.

Categories
Non classé

Cong

Stéphane Sudre vient de publier un nouveau logiciel du nom de Cong. Ce logiciel fait écho à sa présentation de novembre à Cocoa Heads Paris, où il nous parlait d’un contrôle qualité artisanal d’une application. Je me rappelle lui avoir dit que ces contrôles prenaient trop de temps pour que je les fasse à chaque version de l’application… Cong est la solution.

Pour comprendre à quoi sert ce logiciel, analysons une application; par exemple PortraiMatic:

CongPortraiMatic

Cong recherche les anomalies dans les ressources de l’application. Elles sont ensuite classées dans trois catégories: erreur, avertissements et remarques.

Pour PortraiMatic, sont ainsi signalées des erreurs de typographie, des erreurs sur la clé CFBundleTypeExtensions d’Info.plist, et d’autres erreurs liées à Sparkle. Il ne me reste plus qu’à les corriger pour une prochaine version.

Categories
Non classé

Mac App Store: soumettre l’application

Après avoir préparé l’application et implémenté la vérification du reçu, nous sommes enfin prêts à soumettre notre application à Apple pour qu’elle soit publiée sur son magasin. Cette étape n’est pas très compliquée, mais est mal documentée.

Note: Cet article a été établi en utilisant la version 3.2.5 de Xcode. Certaines procédures ont pu évoluer.

Installer Application Loader

Si ce n’est pas déjà fait, téléchargez Application Loader depuis la section Mac d’Apple Developer. À présent, dans Xcode, l’article de menu ”Build > Build & Archive” devrait être dégrisé.

Préparer l’application

Sous iTunes Connect, créez l’application et renseignez sa fiche. L’application doit se trouver dans l’état “Prepare For Upload”

Générer les certificats

Suivez les instructions d’iTunes Connect. Vous devez vous retrouver avec deux certificats dans le Trousseau d’accès: 3rd Party Mac Developer Application: MaBoite 3rd Party Mac Developer Installer: MaBoite.

Les certificats se trouvent dans le trousseau Système. Copiez-les dans le trousseau Session, autrement, Xcode ne saura pas les trouver.

Signer l’application

Retour à Xcode. Affichez la rubrique Build des infos de la cible. Pour la configuration Release: Code Signing Identity 3rd Party Mac Developer Application: MaBoite

Sélectionnez l’article de menu ”Build>Build & Archive”.

Soumettre l’application

  • Dans l’organiseur, nommez l’archive.
  • Cliquez le bouton ”Submit…”
  • Dans la boîte de dialogue, dans le menu qui donne le choix du certificat, sélectionnez “Don’t Sign” puis sélectionnez “3rd Party Mac Developer Installer: MaBoite”. Changer la sélection est nécessaire à cause d’un bug de Xcode 3.2.5. !
  • Dans l’organiseur, si un point d’interrogation apparaît à la place de l’icône de l’application: Un bug de Xcode oblige à fournir le nom complet de l’icône, avec son extension. Dans Info.plist, changez le nom de l’icône, par exemple de ”AppIcon” à ”AppIcon.icns”.

Et voilà, il n’y a plus qu’à attendre la réponse d’Apple.

Categories
Non classé

Mac App Store: vérifier le reçu

Dans l‘article précédent, je vous expliquai comment maintenir à la fois une version de votre application pour le Mac App Store et pour votre site web. Dans le présent article, nous verrons comment se prémunir du piratage de l’application en validant le reçu fourni par Apple.

Le reçu

Un répertoire _MASReceipt est incorporé au bundle de l’application téléchargée sur le Mac App Store:

.../SampleApp.app/Contents/_MASReceipt/receipt

Ce reçu constitue la pierre angulaire de la protection anti-pirate. Il s’agit de vérifier qu’il a bien été émis par Apple et que son contenu correspond bien à notre application. Malheureusement, Apple ne fournit pas d’API pour effectuer ces vérifications. Devant la difficulté de concevoir un service invulnérable, Apple a baissé les bras et s’est déchargée du travail sur nos épaules de développeurs. C’est donc à chaque application de faire les vérifications, qui n’ont rien de trivial!

Code d’exemple de Roddi

Apple a rédigé un document (réservé aux développeurs inscrits) qui décrit le contenu d’un reçu et les étapes de la validation. Comme vous le verrez, les indications pour l’implémentation concrète sont laconiques. Le but avoué est d’éviter que tous les développeurs utilisent le même code de validation. Le problème, c’est que peu de développeurs possèdent les connaissances nécessaires pour implémenter ces vérifications. Face à cette complexité, des développeurs ont décidé de créer une solution open-source: Roddi-ValidateStoreReceipt. On trouve aussi cet exemple d’Alan Quatermain, qui fut précurseur mais est moins abouti. Attention toutefois, il ne faut en aucun cas réutiliser ce code tel quel: il serait trop facile à repérer et modifier.

Les étapes de la validation

Comparons un peu la solution de Roddi et les préconisations d’Apple.

Vérifier la signature du reçu

Apple donne quelques indications pour vérifier la signature du reçu en utilisant OpenSSL, et indique qu’il faut utiliser le certificat Apple Root CA, mais pas comment l’obtenir. Le code de Roddi va chercher le certificat dans le Trousseau. Celui de Quatermain le récupère sur le site d’Apple, ce qui présente le défaut d’exiger un accès à Internet au lancement de l’appli.

Extraire les informations de la “Payload”

La partie “Payload” du reçu comprend les informations que nous allons vérifier par la suite: Bundle Identifier, version de l’appli, une valeur opaque (=aléatoire) et un hâchage. Apple préconise l’utilisation d’un obscur outil en ligne de commande, asn1c, pour décomposer la Payload. J’ai installé macports, installé asn1c et généré grâce à lui un fichier C permettant la décomposition.

Voici mon constat:

  • ne vous ennuyez pas à installer asn1c. Le code C qu’il a génèré est intégré au projet de Quatermain.
  • le code produit est dégueulasse. À vous les warnings de GCC dans tous les sens. Roddi a adopté une autre solution: la Payload est décomposée grâce à OpenSSL, ce qui dispense d’embarquer le code d’asn1c dans votre projet.

Vérifier le Bundle Identifier et la version

Comparez le Bundle Identifier de votre appli (pour moi, ”com.ceroce.PortraiMatic”) à celui du reçu. Ceci garantit que le reçu correspond bien à votre appli, et qu’on n’a pas remplacé le reçu de votre appli par celui d’une autre appli… (Hein, Angry Birds!) Faites de même pour la version: vous ne voudriez pas que l’utilisateur utilise le reçu de la version 1.5.3 pour valider la version 2.1.0… Il peut être tentant de récupérer ces deux informations depuis Info.plist: mauvaise idée. Ce fichier peut être modifié sans impact sur le reçu. Stockez le Bundle Identifier et la version ”en dur” dans votre code. De même, évitez — en les obscurcissant — que ces deux chaînes apparaissent quand on ouvre l’application avec un éditeur hexa. Notez que le code de Roddi compare les chaînes en dur avec celles d’Info.plist pour éviter les étourderies.

Vérifier le GUID

Le GUID est en fait l’adresse mac de l’ordinateur autorisé. Pour une fois, Apple fournit du code pour la récupérer (adopté tel quel chez Roddi). Il faut concaténer le GUID + la valeur opaque + Bundle Identifier et appliquer au tout un hâchage SHA-1. Ce hâchage doit correspondre au hâchage stocké dans la payload. !!! En conclusion Nous l’avons vu, la validation n’est pas facile. Heureusement, d’autres ont déjà essuyé les plâtres! Peut-être qu’Apple nous proposera une solution plus simple dans un avenir proche.

Categories
Non classé

Adapter son appli au Mac App Store

Si vous proposiez déjà une application pour Mac et que vous souhaitez qu’elle soit disponible sur le Mac App Store, quelques modifications s’avèrent nécessaires. Le présent article prodigue quelques astuces pour créer la version pour le magasin d’Apple, tout en conservant la version distribuée sur votre site web.

S’assurer que l’application peut être commercialisée sur le MAS

Avant toute chose, il faut vous assurer que votre application pourra respecter les restrictions d’Apple. Il s’agit essentiellement que son installation puisse se faire par une simple copie.

BWToolkit

Apple interdit d’appeler des méthodes privées de ses API. Il se trouve justement qu’une framework très populaire, BWToolkit, fait appel à quelques API privées de NSTokenAttachmentCell. L’auteur est au courant; en attendant, il est possible de recompiler la framework en supprimant le code en défaut.

Enregistrement des données

Comme je l’expliquai, le but d’Apple est que la désinstallation de l’application soit aussi simple que sous iOS. Elle impose pour cela des restrictions quant aux répertoires destinés à accueillir les données de l’utilisateur. Pour ma part, j’ai dû changer le chemin d’enregistrement de la galerie des portraits de utilisateur/ Documents à utilisateur/ Bibliothèque/ Application Support/ PortraiMatic.

Nouvelle configuration ou nouvelle cible ?

Passons aux choses sérieuses. Apple impose que l’application pour le MAS ne contienne pas:

  • de code PowerPC. Le MAS n’étant disponible qu’à partir de Mac OS 10.6.6, qui ne tourne que sur processeurs Intel.
  • des frameworks pour mettre à jour l’application. Ici, on parle évidemment de Sparkle, dont l’absence est vérifiée par les validateurs d’Apple.
  • des messages/boites de dialogues qui invitent à entrer un code de débridage. Ma première idée fut de créer une nouvelle “build configuration” pour le MAS. Seulement, cette tactique fonctionne mal: il est difficile de retirer des éléments. Par exemple, pour retirer Sparkle, il faudrait ajouter un script qui supprime la framework de l’application. Tout est à l’avenant: par exemple, il faut retirer des Préférences les rubriques liées aux Mises à jour et au débridage du logiciel. Finalement, il est plus simple de créer une cible (target) spécifique au MAS, pour incorporer ou retirer des fichiers à volonté.

Création d’une nouvelle cible

Dupliquez la cible actuelle par un clic droit > Duplicate Target. Renommez-la, en quelque chose comme MonAppMAS.

Modifier les configurations de la cible MAS

Affichez les build configurations de la cible. Nous modifions toutes les configurations (Debug, Release…).

Architectures i386 x86_64
Nous compilons pour les architectures Intel 32 et 64 bits.

Base SDK Mac OS 10.6
Le MAS n’étant disponible qu’à partir de 10.6.6, adoptons la dernière version du SDK.

Valid Architectures i386 x86_64
Liste des architectures éventuellement à compiler. Seules celles qui se trouvent à la fois dans cette liste et dans ‘Architectures’ seront compilées.

Build Locations Build Product Path build/MAS
Nous créons un sous-dossier dans le répertoire Build pour la version réservée au MAS. Modifiez également ce paramètre pour la cible originelle, par exemple en build/MonSite. En effet, certaines ressources sont références par des chemins relatifs au répertoire Build; il faut alors que le Build Product soit enfoui dans un même nombre de sous-répertoires.

GCC 4.2 – Preprocessing Preprocessor Macros Not Used in Precompiled Header MAC_APP_STORE
Je définis un symbole MAC_APP_STORE qui sera utilisé dans le code pour faire de la compilation conditionnelle:

#ifdef MAC_APP_STORE 
NSLog(@"Version pour le Mac App Store"); 
#else 
NSLog(@"Version pour mon site web"); 
#endif

Packaging Info.plist File Info.plist
En dupliquant la cible, Xcode a aussi créé un deuxième fichier Info.plist. Nous n’en voulons qu’un seul pour les deux cibles, aussi nous supprimons ce deuxième fichier et déclarons le même fichier.

Preprocess Info.plist File YES
Ceci active une étape de pré-traitement sur le fichier Info.plist. Nous l’activons pour permettre sa compilation conditionnelle.

Info.plist Other Preprocessor Flags -traditional
Une fois le pré-traitement activé, le compilateur considère que les // indiquent le début de commentaires. Cela pose problème avec les URL (http://monsite.com). Passer le drapeau -traditional au compilateur l’oblige à considérer que les commentaires ne peuvent être délimités que par /* et */ comme dans le langage C traditionnel. Plus d’infos par ici.

Info.plist Preprocess Definitions MAC_APP_STORE
Nous définissons le symbole MAC_APP_STORE pour la compilation d’Info.plist.

Search Paths Framework Search Paths
Il faut reprendre ces chemins pour supprimer les frameworks inutiles (ex. Sparkle.framework) mais également pour supprimer les / que Xcode ajoute malencontreusement aux chemins, lors de la duplication de la cible. Il s’agit d’un bogue de Xcode 3.2.5.

Editer Info.plist

Les réglages plus haut permettent l’utilisation de la compilation conditionnelle. Clic doit sur Info.plist > Open As > Source Code File…

#ifdef MAC_APP_STORE 
<LSMinimumSystemVersion> <10.6.6>
<LSApplicationCategoryType><public.app-category.photography>
#else 
<LSMinimumSystemVersion><10.5.0>
<SUEnableAutomaticChecks>
<SUPublicDSAKeyFile><dsa_pub.pem>
<SUFeedURL><http://ceroce.com/portraimatic/appcast.xml>
#endif

N’avoir qu’un seul Info.plist est intéressant parce que seule une poignée de clef sont différentes pour la MAS.

Retirer les sources et ressources inutiles

Demandez les infos sur le fichier source ou ressource pour le retirer de la cible à laquelle il n’appartient pas et donc réduire la taille de l’application. À noter qu’il peut être nécessaire de créer deux fichiers ressources. Par exemple, j’ai dû créer un fichier PreferencesMAS.xib, pour que ne soient pas affichées les rubriques liées aux Mises à jour de l’application.

Pour la suite

À ce stade, vous devriez avoir deux applications bien différenciées. Il reste encore deux étapes avant la soumission à Apple:

  • signer l’application
  • implémenter la vérification du reçu d’Apple

Ce sont deux étapes complexes qui feront l’objet d’un autre article.

20 mai 2011: Mise à jour

Voici quelques précisions supplémentaires sur Info.plist et sa compilation conditionnelle:

  • J’ai fait une fausse manipulation pour la version PortraiMatic actuellement proposée sur le MAS: j’avais bien modifié le fichier Info.plist comme indiqué ci-dessus; cependant j’ai eu le malheur d’afficher son contenu dans Xcode en mode ”graphique” et d’enregistrer, si bien qu’Xcode a fait disparaître sa compilation conditionnelle. De fait, les clefs de Sparkle apparaissent dans l’Info.plist et la version minimum du système d’exploitation est fixée à 10.5. Apple a validé cette application sans broncher.
  • Louka Desroziers a eu quelques soucis, en voulant imbriquer des #ifdef. Il faut absolument qu’ils soient placés en début de ligne (sans espace avant).