Blogue

Mac App Store

Les nouvelles d’Apple cette semaine sont intéressantes. Premièrement, on aura bientôt un App Store pour le Mac. Deuxièmement, on a eu droit à un petit aperçu de Mac OS X Lion. Et finalement, le MacBook Air vient maintenant avec un écran à plus haute résolution. Mais parlons du App Store.

Le Mac App Store est une bonne idée selon moi, à tout de moins en principe. Puisqu’il ne sera pas exclusif, il ne bloquera pas les autres méthodes de distribution. Mais il aidera les utilisateurs à trouver et installer des applications, deux choses qui méritaient d’être amélioré. Certainement, les règles du App Store vont disqualifier plusieurs applications existante qui ne pourront s’y trouver, mais même pour celle qui répondent aux critères d’Apple, ça peut devenir un petit casse-tête.

Un des problèmes sera le système de licence. Les développeurs sont présentement responsable des licences qu’ils offrent pour leur application. Les applications d’aujourd’hui contiennent généralement du code qui vérifie qu’une licence valide existe, ce qui permet au développeur d’offrir des conditions correspondantes à son marché cible.

Avec le App Store, Mac OS lui-même se charge des licences. C’est bien beau, mais ça veux dire que si un développeur veut offrir son application en dehors du App Store, il aura besoin de maintenir deux versions différentes : l’édition pour le App Store sans code de licence, et l’édition régulière qui nécessite un numéro de série ou quelque chose de similaire.

Maintenir deux versions n’est pas terriblement compliqué, même si c’est un peu plus de trouble. Mais pourquoi est-ce qu’un développeur se préoccuperait de ça au lieu de seulement vendre sur le App Store ? Une première raison est qu’il fera plus d’argent avec son propre magasin. Aussi peu que l’on pourrait trouver la part de 30% qu’Apple s’accorde sur les ventes du App Store, vendre sur son propre magasin en-ligne reste moins cher. Si par exemple vous utilisez Kagi, Fastspring, ou Esellerate pour créer votre magasin, ils s’occuperont des paiements pour vous, et ne prendront qu’environ 10% du montant. Tout ce que vous avez à faire est d’écrire votre générateur de numéro de série et d’intégrer un vérificateur de ces numéros dans votre application. Bien sûr, le App Store aura des DRM plus solides et affichera votre application dans son catalogue, mais est-ce que ça vaut les 20% restant ? Si je place une application sur le App Store, je lui donnerai probablement un prix plus élevé sur le App Store que sur mon propre magasin en-ligne, puisque je pourrai baisser le prix sur mon magasin tout en récoltant autant d’argent.

Une deuxième raison pour un développeur de maintenir son propre magasin en-ligne est de garder son indépendance. Comme l’App Store de l’iOS l’a montré, vous n’êtes jamais certain qu’Apple n’enlèvera pas votre application de leur magasin. Plus probable encore est qu’un développeur veuille ajouter une fonction qu’Apple n’aime pas. Si ça devait arriver, il est probable que cette fonction se retrouve dans l’édition régulière de l’application tout en étant exclue de l’édition du App Store. Sur un deuxième point les clients du App Store sont perdants.

Bien que ça fasse du sens pour un développeur de vendre son application sur le Mac App Store, si ce n’est que pour la visibilité que ça donne, ce n’est pas nécessairement un bon « deal » pour le consommateur de l’acheter par là. Des DRM plus strictes combiné à la possibilité que certaines fonctions soit exclues pour accommoder Apple et la possibilité que le prix soit plus cher ; ça vaut probablement mieux aller voir le magasin du développeur d’abord.

Il y a une exception cependant : si vous ne faites pas confiance au développeur du logiciel, peut-être serez-vous plus en confiance avec la version qu’Apple a validé. D’un autre côté, si vous ne faites pas confiance au développeur, utiliseriez-vous vraiment son application en premier lieux ?


Javascript Off

Je navigue de plus en plus fréquemment sur le web avec Javascript désactivé. Un développeur web pourrait croire que j’essaie de briser l’expérience qu’il a créé pour son site web, mais pour moi la plupart du temps je trouve ça plus plaisant. Bien que je soi sur un Core 2 Duo, le web est sensiblement plus rapide avec Javascript désactivé.

Javascript est étonnement rapide de nos jours, et tous les navigateurs se vantent de la vitesse de leur moteur Javascript. Mais même si Javascript s’exécute vite, ça ne signifie pas que tous les scripts sont bien écrits pour rouler vite. De plus, tout ça n’affecte pas la latence associée au chargement des scripts ni l’activité réseau supplémentaire souvent générée par le script lui-même. Simplement pour la vitesse, ça vaut la peine d’essayer.

Un second avantage est d’éviter le pistage (tracking). En l’absence de Javascript, la seule méthode fiable permettant de vous retracer est d’utiliser des bons vieux cookies. Avec Javascript activé, les sites web disposent de beaucoup d’autres moyens. Et ça devient très difficile de se débarrasser de ces étiquettes collantes ; essayez de détruire un evercookie par exemple. Je ne suis pas paranoïde, mais parfois je préfère que certaines choses restent privées et je ne veux pas qu’une compagnie publicitaire connaisse mon historique de navigation. En désactivant Javascript, c’est un souci de moins.

Le gros désavantage est évidemment que, pour certain sites, Javascript est pas mal obligatoire. Vous ne pouvez voir un vidéo Youtube sans Javascript par exemple, même avec le lecteur HTML5 activé. À mon avis, c’est simplement un mauvais design ; Javascript ne devrait pas être requis pour naviguer sur quelque site web que ce soit, excepté quand le contenu lui-même ne pourrait exister sans script (ce jeu par exemple).

Présentement, quand je trouve un site web où ça vaut la peine d’activer Javascript, je tape Commande-Virgule et je coche la case Javascript dans les préférences de Safari, et je répète le processus pour le désactiver par la suite. C’est plus compliqué, et donc parfois je laisse tomber certains sites et trouve autre chose à regarder.

Et c’est pas mal la même histoire pour Flash.


D/Objective-C: frappé un mur, nouveau départ

Il y a environ trois ans, je travaillais sur un petit projet à moi qui consistait à utiliser les capacités de « template » du langage de programmation D pour créer un pont entièrement transparent avec la runtime Objective-C. Ça fonctionnait plutôt bien : les objets pouvait passer sans soucis entre les deux monde et c’était plutôt simple d’écrire des bindings pour les classes Objective-C. Ça n’a pas pris beaucoup de temps avant que quelque failles apparaissent…

Les failles

Le premier problème était que c’était atrocement lent de compiler quoi que ce soit avec le pont. Bien que j’ai réussi à réduire le temps de compilation par un facteur 2 ou 3, ce n’est pas encore qualifiable de rapide. Mais ce n’est pas un défaut fatal.

Un deuxième problème était les petites inefficacités un peu partout. Normalement, compiler un objet Objective-C construit un fichier objet avec un format particulier que le linker dynamique et la runtime Objective-C se chargent d’initialiser ce qui le doit. Mais c’est impossible à faire en D, je doit donc tout initialiser à l’exécution du programme, et ceci à la demande (lazily) pour éviter de créer des dépendances circulaires entre les modules ayant des constructeurs statiques. Il y a beaucoup de code à cet effet dans le pont.

En conséquence de cette initialisation à la demande, les bindings doivent parfois être initialisées manuellement. C’est le cas par exemple avant de charger un fichier nib. C’est pas vraiment idéal.

Mais le véritable blocage et la taille du code généré par les bindings. Le système j’ai créé doit générer beaucoup de code pour chacune des fonctions et classes pour lesquelles on crée des bindings. Ceci gonfle de beaucoup la taille de l’exécutable final (et pourrait en partie expliquer la lenteur de compilation). La petite application de test incluse avec le pont utilise environ 60 Mo de code (compilé), la même chose écrite en Objective-C prendrait quelque kilooctets.

Ceci n’était pas le cas au début. Tout ce bagage est apparut au fur et à mesure que j’ai ajouté des bindings pour différentes classes de Cocoa. C’est un véritable problème parce que personne ne veut distribuer un exécutable avec 60 Mo de code qui restera inutilisé la plupart du temps. Une solution pourrait être que chacun écrive des bindings contenant uniquement les classes et méthodes don’t il se sert, mais c’est d’un intérêt plutôt limité.

Une nouvelle approche

Alors comment rendre les bindings plus légers et éviter le non-sens qu’est initialisation à la demande ? Il y a une façon : inclure le modèle d’objet d’Objective-C dans le compilateur. Si le compilateur comprend ce qu’est un objet Objective-C, comment appeler ses méthodes et comment générer le fichier objet, il deviendra aussi bon qu’un compilateur Objective-C avec comme seule différence la syntaxe qui sera celle du D.

Alors c’est donc ce que j’ai entrepris ce dernier mois. J’ai joué avec le code source de DMD et tenté de lui faire générer du code à la Objective-C.

Il n’y a qu’une seule chose de fonctionnelle actuellement : déclarer une interface extern (Objective-C) et appeler des fonctions sur elle. Ça fonctionne comme ceci :

extern (Objective-C)
interface NSObject {
    NSObject description();
}

Maintenant, quand vous avez une instance de NSObject dans la variable objet, vous pouvez écrire objet.description() et ce sera équivalent à écrire [objet description] en Objective-C. À l’interne, l’appel est transformé en objc_msgSend(objet, @selector(description)). J’ai ajouté au compilateur la capacité de placer le sélecteur dans le segment __OBJC,__message_refs où il est automatiquement enregistré par la runtime lors du chargement de l’exécutable. C’est exactement ce que fait le véritable compilateur Objective-C, et c’est beaucoup mieux que de générer tout plein de code pour enregistrer le sélecteur à la demande lors de l’exécution.

Pour les méthodes ayant plus d’un argument, le compilateur ne peut déduire le nom d’un sélecteur à partir du nom de la fonction parce que le sélecteur est généralement séparés en plusieurs parties. Donc j’ai du ajouter une syntaxe permettant de spécifier manuellement le sélecteur pour la fonction. Ça ressemble à ça :

extern (Objective-C)
interface NSString {
    void getCharacters(wchar* buffer, NSRange range) [getCharacters:range:];
}

Et ça marche aussi ! De cette façon, appeler string.getCharacters(b, r) émet le même code que l’appel Objective-C [string getCharacters:b range:r].

Tout ceci est bien, mais toujours incomplet. Pour l’instant vous devez trouver un pointeur vers un objet Objective-C, le « caster » dans le type de la bonne interface, puis ensuite appeler des fonctions. C’est pas si mal, mais ce n’est pas très utile en soit non plus. Il y a encore beaucoup de travail pour rendre Cocoa utilisable avec le D.

Mais le débrousaillage est fait, il sera maintenant plus facile de continuer. Ça prendra certainement plusieurs mois encore avant que ça marche bien, plus ou moins dépendant du temps que je peut dévouer à ce projet. Je veux que le résultat final permette de mélanger des objets Objective-C et D de façon transparente, et la possibilité de créer des classes dérivées de classes Objective-C.

Si vous aimeriez utiliser D avec Cocoa sur Mac, j’aimerai bien avoir vos impressions. Et si vous voulez m’encourager plus, vous pouvez faire un don : si je reçoit suffisamment de support ce sera probablement plus facile de dévouer plus de temps à ce projet.


Vente du mois d’août: 35 % de rabais sur Magic Launch

Une chose qu’on réalise quand on vent son propre logiciel est que ça ne fourni pas un revenu très stable. On peut avoir 20 ventes une journée et zéro le lendemain, sans raison apparente. Même la moyenne mensuelle varie significativement d’un mois à l’autre. Mais durant l’été, les ventes ont diminuées considérablement. Alors j’ai pensé à faire quelque chose…

En vue de grossir les ventes cet été, je coupe de 35 % le prix de Magic Launch. Cette offre est valide pour tout le monde. Pas de code de coupon, pas de limite sur le nombre d’utilisateur de la licence. Et même pas besoin de savoir qu’il y a une vente : vous n’avez qu’à vous rendre sur la page d’achat de Magic Launch et vous obtenez automatiquement le prix réduit. Ceci durera jusqu’à la fin du mois d’août.

Peut-être qu’il faut s’y attendre à ce que les ventes baissent avec tout le monde qui prennent leurs vacances l’été. J’espère certainement que ce n’est que passager que pas parce que les gens ne veulent plus de Magic Launch. Je sais en tout cas que certains d’entre vous attendent une promotion pour faire leur achat. Si vous êtes de ce groupe, c’est maintenant votre chance.



  • © 2003–2024 Michel Fortin.