Vos débuts en Cocoa

19 11 2008 In: Cocoa, Objective-C

Comme promis, cet article sera plus concret que les précédents, je ne vais toutefois pas vous épargner la théorie puisque nous allons aborder un concept important pour Cocoa, le paradigme M-V-C, et voir quelques rudiments du langage Objective-C et de l'utilisation de nos deux outils, XCode et Interface Builder.

Le programme d'exemple

Afin d'être plus concrètes, les explications s'articuleront autour d'un programme simple, pas très éloigné de l'exemple classique d'Apple, à savoir, le convertisseur de monnaie. Cependant, je m'adresse ici à des programmeurs chevronnés qui voudront rapidement en venir aux faits.

Le principe de notre programme est le suivant: une fenêtre comprend deux champs éditables. Taper une température dans le champ Degrés Fahreinheit et valider fait apparaître la conversion dans le champ Degrés Celcius et vice-versa.

Le paradigme M-V-C

À l'instar d'autres bibliothèques de développement, Cocoa est basée sur le paradigme Modèle-Vue-Contrôleur, qui sépare les Vues (l'interface utilisateur) du Modèle (la partie qui conserve les données et effectue les calculs). Le Contrôleur fait les liens entre les deux couches.

MVC

Création du projet

XCode impose la création d'un projet pour regrouper les différents fichiers constituant l'application et définir ses paramètres de construction.

Sous XCode, sélectionnez le menu File > New Project… > Application > Cocoa Application. Cliquez sur Next, tapez un nom pour le projet, et choisissez sa localisation. La fenêtre du nouveau projet s'ouvre; il y a déjà quelques fichiers dans le projet.

Programme principal

Jetez un œil à main.m, dans la rubrique Other Sources:

    #import <Cocoa/Cocoa.h>

    int main(int argc, char *argv[])
    {
        return NSApplicationMain(argc,  (const char **) argv);
    }

Nous reconnaissons la forme canonique utilisée en C pour la fonction main(). Elle ne fait qu'appeler NSApplicationMain() qui va essentiellement créer une instance de la classe NSApplication.

La directive de compilation #import est similaire à #include, si ce n'est qu'un fichier déjà inclus ne le sera pas une seconde fois. On inclut ici cocoa.h qui se trouve dans le framework Cocoa.

Ressources

Dans la rubrique Resources , vous trouverez trois fichiers:

  • Info.plist Comme vous le voyez, il s'agit d'un fichier XML. Vous pouvez d'ailleurs éditer les fichiers .plist grâce à l'utilitaire Property List Editor, mais ce fichier-là peut être édité d'une façon plus conviviale (…c'est vite dit) dans XCode (menu Project > Edit Active Target).

  • InfoPlist.strings Les fichiers .strings servent à traduire une application dans une autre langue — ce qu'on dénomme souvent par le vilain anglicisme localiser. Les clefs y sont associées aux texte traduits. Ce fichier-ci est utilisé pour le texte s'affichant dans la boîte de dialogue À propos de…

  • MainMenu.nib Ce fichier contient des éléments d'interface utilisateur. Double-cliquez-le pour l'ouvrir dans Interface Builder… il y a déjà du monde à l'intérieur.

Couche Vue

Faîtes en sorte que la fenêtre Window ressemble à ceci:

Fenetre

Vous trouverez les éléments dans la palette Library (menu Tools > Library), dans la rubrique Cocoa > Views & Cells. Les champs éditables sont des Text Fields. Les intitulés sont des Label.

Couche Modèle

Nous allons ici créer la classe CFRConvertisseur. Pourquoi pas Convertisseur tout court ? Traditionnellement, les noms de classes commencent par un suffixe pour éviter des conflits (il n'existe qu'un namespace par application). Les classes de Cocoa commencent par NS pour… Next Step.

Sous XCode, dans la fenêtre du projet, sélectionnez la rubrique Classes. Sélectionnez le menu File > New File… > Cocoa > Objective-C Class. Cliquez sur Next, vous serez alors invités à saisir le nom. Tapez donc CFRConvertisseur.m. Puis cliquez sur Finish. Deux fichiers, CFRConvertisseur.m et CFRConvertisseur.h, sont alors insérés dans le projet. Ouvrez donc le .h :

    #import <Cocoa/Cocoa.h>

    @interface CFRConvertisseur : NSObject {

    }

    @end

C'est ainsi que l'on déclare une classe en Objective-C. NSObject est l'objet de base, dont héritent tous les objets, à de rares exceptions près.

On place entre les accolades les définitions des variables d'instances (variables membres). Notre programme n'en nécessitant pas, nous les laissons vides. Nous définissons, entre l'accolade } et @end, les méthodes. Comme nos méthodes n'accèdent pas aux variables d'instance, nous les déclarons comme des méthodes de classes (ce qu'on appellerait des méthodes "statiques" en Java), en les précédant du signe + .

    + (float) convertirCelciusEnFahrenheit:(float)celcius;
    + (float) convertirFahrenheitEnCelcius:(float)fahrenheit;

Pour info: les méthodes d'instances sont précédées du signe - .

Copiez ces deux lignes et ouvrez CFRConvertisseur.m.

Pour ouvrir le .m correspondant au .h courant, et vice-versa, cliquez sur la petite icône counterpart (en haut à droite) ou bien utilisez le menu View > Switch to Header / Source File.

Collez les prototypes des méthodes, afin d'implémenter les formules de conversion:

    #import "CFRConvertisseur.h"

    @implementation CFRConvertisseur

    + (float) convertirCelciusEnFahrenheit:(float)celcius
    {
        return (9.0/5.0) * celcius + 32.0;
    }

    + (float) convertirFahrenheitEnCelcius:(float)fahrenheit
    {
        return (5.0/9.0) * (fahrenheit - 32.0);
    }

    @end

Couche contrôleur

Et maintenant, nous programmons la couche contrôleur, qui fait le lien entre les vues et le modèle. Créez un nouveau fichier source, appelé CFRControleur.m.

Déclarations des outlets

Ouvrez CFRControleur.h. Tout d'abord, nous déclarons les outlets:

    @interface CFRControleur : NSObject {
        IBOutlet NSTextField*   champFahrenheit;
        IBOutlet NSTextField*   champCelcius;
    }

Les outlets sont des variables d'instance, quand notre classe CFRControlleur sera instanciée (à la lecture du fichier .nib), Cocoa fera pointer les variables sur les objets que nous leur auront lié. Nous allons voir ces liaisons dans un instant. Ecrire IBOutlet est nécessaire pour qu'Interface Builder sache qu'il s'agit d'outlets.

N'oubliez pas de rajouter #import "CFRConvertisseur.h"

Déclaration des actions

    @interface CFRControleur : NSObject {
        IBOutlet NSTextField*   champFahrenheit;
        IBOutlet NSTextField*   champCelcius;
    }

    - (IBAction) fahrenheitModifie:(id)sender;
    - (IBAction) celciusModifie:(id)sender;

    @end

Les actions sont des méthodes qui sont appelées lorsqu'un contrôle est actionné. Pour nos champs, cela signifie qu'on aura validé leur contenu en tapant sur Entrée. Une action a forcément un prototype de cette forme. id est le type générique des objets. Nous savons évidemment qu'il s'agit de NSTextFields.

Regardez donc à quoi correspond le symbole IBAction

Sous XCode, pour accéder à la définition d'un symbole, maintenez la touche Commande appuyée, et double-cliquez le symbole.

On peut voir qu'IBAction est équivalent à void et qu'IBOutlet équivaut à rien.

Liaison des Outlets et Actions

Retournez sous Interface Builder. Faîtes apparaître la palette Library (menu Tools > Library). Dans la rubrique Library > Cocoa > Objects & Controllers, vous trouverez un cube bleu, intitulé NSObject. Glissez-le dans la fenêtre MainMenu.nib. Ainsi, Cocoa instanciera un objet de la classe NSObject à l'ouverture du .nib… mais ce n'est pas ce que nous voulons ! Sélectionnez le cube, puis dans la palette Inspector > Object Identity mettez le champ Class à CFRControleur. Vous remarquerez que les actions et outlets sont apparues au bas.

Cliquez sur le cube bleu en maintenant la touche Contrôle appuyée (ou bien clic droit), et reliez le cube au champ Fahrenheit. Quand vous lâchez le bouton, un menu apparaît: choisissez champFahrenheit. Et voilà! L'outlet, champFahrenheit est liée au champ la représentant. Faîtes de même pour le champ Celcius.

Pour les actions, c'est pareil, mais en tirant un segment du champ vers le cube. Je vous laisse faire.

Implémentation des actions

Revenons à XCode et à CFRControleur.m, pour y ajouter les deux méthodes d'actions:

    - (IBAction) fahrenheitModifie:(id)sender
    {
        // Afficher la température convertie dans le champ Celcius
        float fahrenheit = [sender floatValue];
        float celcius = [CFRConvertisseur convertirFahrenheitEnCelcius:fahrenheit];
        [champCelcius setFloatValue:celcius];
    }

Remarquez le [sender floatValue]. Il s'agit d'un appel de méthode, qu'on appelle plus volontiers un message en ObjC. Nous savons que sender est notre NSTextField Fahrenheit. Nous lui demandons de nous envoyer sa valeur sous la forme d'un float.

[CFRConvertisseur convertirFahrenheitEnCelcius:fahrenheit] est également un message, mais comme convertirFahrenheitEnCelcius: est une méthode de classe, nous la faisons précéder du nom de sa classe.

Finalement, nous demandons au champ Celcius d'afficher la valeur celcius.

Ajoutons l'autre méthode:

    - (IBAction) celciusModifie:(id)sender
    {
        // Afficher la température convertie dans le champ Fahrenheit
        [champFahrenheit setFloatValue:[CFRConvertisseur convertirCelciusEnFahrenheit:[sender floatValue]]];
    }

Cette méthode est similaire à la précedente, si ce n'est que j'ai imbriqué les messages.

Terminez par ajouter

    #import "CFRConvertisseur.h"

Alors ça marche ?

Nous n'avons plus qu'à lancer le programme: menu Run > Run. Ça doit compiler et lancer l'application. Je vous laisse jouer et essayer quelques valeurs.

Quelques améliorations

Vous aurez peut-être remarqué que le programme souffre de deux défauts:

  • trop de chiffres sont affichés (c'est inesthétique)

  • si on entre des caractères plutôt que des chiffres, cela revient à taper zéro (c'est mal).

Retournez sous Interface Builder. Dans la palette Library > Library > Cocoa > Views & Cell, recherchez le Number Formater (un rectangle avec un $ ). Glissez-le sur le champ Fahrenheit. Allez dans la première rubrique de l'Inspecteur (Number Formater Attributes), et mettez-y le menu Style à Decimal. Faîtes de même pour le champ Celcius.

Retournez sous XCode, relancez l'application… les deux défauts sont réglés !

Pour finir

Cet article n'était qu'une introduction, mais vous a cependant présenté les concepts de bases de Cocoa: MVC, édition des .nib, Outlets et actions. Les prochains articles vous aideront à approfondir ces connaissances.

Le projet complet à télécharger, si vous n'avez pas réussi.

Le garbage-collector de Leopard

13 11 2008 In: C, Cocoa, Objective-C

Pour ceux que cela interresserait, Le code du garbage collector de Leopard est disponible sous licence Apache 2.0 depuis peu. Le projet s'appelle AutoZone et il est aussi bien utilisé dans Cocoa que dans MacRuby. Il est disponible sur le site Open Source d'Apple :

En vrac

05 11 2008 In: Cocoa, En vrac, Liens

Voici les dernières informations intéressantes sur le monde Cocoa :

L'université de Stanford propose cette année des cours concernant le développement sur iPhone (sous le nom CS193P - iPhone Application Programming). Et si vous n'êtes pas étudiant à Stanford, vous pouvez tout de même suivre le cours grâce aux PDF et aux morceaux de code disponible en ligne sur la page dédié au cours. On notera tout particulièrement :

En espérant voir d'ici quelques temps des vidéos ou des MP3 des cours.

Cocoa et le "monde extérieur"

28 10 2008 In: Cocoa

Il y a actuellement une actualité importante en ce qui concerne Cocoa et le développement multi-plateforme :

  • Trolltech, l'éditeur de Qt, vient de sortir une preview de la version 4.5 de Qt qui supporte Cocoa et les applications 64-bits : Same old, same new: 4.5 Technical Preview.
  • Le blog Mac Daddy World nous présente Cocotron, qui permet de compiler une application Objective-C/Cocoa pour Windows. Tout Cocoa n'est pas disponible, comme par exemple CoreData, mais le projet mérite d'être suivi : Adventures in Cocotron.

Installation des outils développeur

28 10 2008 In: Cocoa, Logiciel

Ça y est, vous vous êtes décidé à vous lancer dans la programmation Cocoa. Bravo, mais il va falloir d'abord installer les outils de développement.

Où trouver les outils

Première bonne nouvelle, ces outils sont gratuits. Vous les trouverez à deux endroits:

  • sur le deuxième DVD de Mac OS X qu'il soit livré avec votre machine ou acheté séparément
  • sur l'Apple Developer Connection (ADC). Il faut s'inscrire sur le site. Il existe plusieurs types de comptes ADC, mais celui de base est gratuit, et vous permettra de télécharger entre autres les outils développeur.

Vous devez savoir que, selon la version de Mac OS X qui anime votre machine, vous ne pouvez pas utiliser n'importe quelle version des outils. Ainsi XCode 2.5 fonctionne sous Mac OS 10.4 et 10.5, mais XCode 3.0 est réservé à 10.5. La version actuelle est la 3.1.1.

Ce qui est installé

Une fois l'installation (des plus classiques) terminée, vous trouverez un dossier Developer à la racine de votre disque dur. Nous n'allons pas ici détailler ce qui fut installé (ne serait-ce que parce que je ne connais pas tous les outils); concentrons-nous sur ceux du quotidien:

XCode

Il s'agit d'un intégré de développement, dédié avant tout au développement Cocoa: un éditeur de texte, un éditeur des paramètres des applications, un modélisateur Core Data et de quoi s'interfacer avec les outils externes.

Les programmes en ligne de commande

XCode est surtout est éditeur de texte amélioré, il n'inclut pas de compilateur, mais fait appel au compilateur libre gnu C (tapez gcc dans le terminal pour vérifier qu'il est bien là), au débogueur gnu debug (gdb), ou au gestionnaire de version subversion (svn).

Vous pouvez évidemment utiliser ces outils indépendamment de XCode, mais il vous est toutefois conseillé d'installer ces outils par le biais de l'installateur de XCode, qui se chargera de bien configurer votre environnement.

Interface Builder

Mon programme favori, qui permet d'éditer les interfaces utilisateur. Nous verrons son utilisation de base dans un très prochain article.

Analyse des performances et débogage

De nombreuses applications sont fournies pour vous aider à améliorer votre application :

  • MallocDebug, ObjectAlloc pour analyser les allocations et les fuites mémoire
  • Instruments, Sampler et Shark pour l'étude des performances et un tas d'autres petites applications plus spécifiques que vous aurez l'occasion d'essayer.

Quartz Composer

Introduit avec Mac OS 10.4, il s'agit d'un programme singulier qui permet de composer des animations en couchant des blocs fonctionnels sur une feuille et en les reliant. Les animations résultantes peuvent être utilisées dans vos applications Cocoa, pour créer des économiseurs d'écran, ou être lues directement par QuickTime. Le formidable PulpMotion repose sur QuartzComposer.

Dashcode

Il s'agit d'un éditeur, à mi-chemin de XCode et Interface Builder, pour concevoir les Widgets. Il permet de concevoir leur interface utilisateur et de saisir directement le code JavaScript.

Nous passerons à quelque chose de plus concret dans le prochain article. En attendant, joyeuse installation !

Développez des applications Cocoa avec MacRuby

20 10 2008 In: Cocoa

Preuve de l'intérêt grandissant des langages dynamiques comme Ruby ou Python parmi les développeurs, Apple vient de publier une article sur le développement d'applications Cocoa avec MacRuby :

Avantages et inconvénients de Cocoa

20 10 2008 In: Articles, Cocoa

Après la courte présentation de Cocoa de la dernière fois, cet article vous aidera à décider s'il s'agit d'une bonne solution de développement pour votre projet.

Avantages

Rapidité de développement

Certains avancent que le développement sous Mac OS X avec Cocoa est 5 fois plus rapide que le même développement sous Windows. Je suis mal placé pour confirmer, mais comparé à d'autres outils que je connais, Cocoa est effectivement très efficace, de part la nature dynamique du langage Objective-C (tout n'a pas besoin d'être figé à la compilation) et de la qualité générale des classes. Il me semble qu'Apple possède également une avance conceptuelle, avec les récentes technologies Core Data et Cocoa Bindings. Cocoa n'est pas toujours suffisante pour coder une application, mais les autres technologies comme Core Audio ou Core Graphics présentent d'excellents compromis puissance/facilité de mise en œuvre. N'oublions pas non plus que Mac OS X est un système Unix, et nous profitons donc des qualités de ces systèmes.

API mâtures

Cocoa est loin d'être une nouveauté, n'étant qu'une évolution d'OpenStep, le système de développement qui existait déjà sous NeXTSTEP avant qu'il ne devienne Mac OS X. Il est connu que Tim Berners-Lee a développé le premier navigateur web et le premier serveur web grâce à OpenStep. Ces outils de développement évoluent depuis plus de vingt ans; malgré leur âge, ils sont toujours sans équivalent sur les autres plateformes.

Comportement standard

Cocoa est ainsi faite que les choses qui sont habituelles sous Mac OS X sont faciles à implémenter. Que ça vous plaise ou non, votre application suivra en grande partie les canons de Mac OS X et les recommandations d'Apple. En fait, votre difficulté sera parfois de déroger à ces standards !

Inconvénients

Portabilité

Cocoa n'existe que sous Mac OS X. Il existe bien une implémentation libre d'OpenStep (http://www.gnustep.org/), mais il lui manque les dernière innovations (la compatibilité avec Cocoa n'a rien de totale), il faut que l'utilisateur l'installe et les auteurs bénévoles la font progresser lentement. De même, le langage Objective-C — le plus habituel pour développer avec Cocoa — n'existe que sur Mac. Certes, Objective-C est intégré au compilateur libre et multiplateforme gnu c, mais ce compilateur est inutile sans les classes de bases (telles que NSObject, NSArray, NSDictionary, etc.).

Pour un développement multiplateforme, mieux vaut donc aller voir ailleurs, ou développer uniquement l'interface graphique avec Cocoa, et le reste en C++, par exemple (on peut mélanger Objective-C et C++ dans certaines limites).

Difficulté

Cocoa n'est pas pour les débutants. N'espérez pas y comprendre grand chose si vous ne connaissez ni le langage C, ni la programmation objet. Elle introduit par ailleurs de nombreux concepts, souvent étrangers aux développeurs formés à d'autres frameworks. Sa puissance est réelle, mais il faudra investir du temps et de l'énergie pour en profiter.

Outils

L'outil principal pour programmer Cocoa, c'est XCode, l'intégré de développement d'Apple. Et comment dire… il s'améliore à chaque version, mais c'est toujours pas ça. Le principal soucis provient de l'éditeur de texte, de sa lenteur, de son indentation automatique agaçante, tout comme sa complétion automatique. Mais on pourrait aussi citer les interfaçages avec gdb (débogueur) et Subversion (gestion de version) moyennement au point, ou encore les outils pour créer des diagrammes de classes, qui eux, sont carrément risibles.

Programmes d'exemple

Je me suis toujours demandé ce que foutait Apple avec ses programmes d'exemple. À moins de tomber sur une perle (mais de mémoire, je ne vois pas), les programmes d'exemple souffrent d'un ou plusieurs des maux suivants :

  • pas commentés, et brouillons
  • purement démonstratifs et inutilisables dans un autre contexte
  • concernent vaguement le sujet
  • inutilement compliqués, voire des pans entiers du source ne servent à rien
  • mémoire gérée à la truelle

Heureusement que d'autres développeurs proposent les leurs.

P'tête ben un avantage, mais p'tête ben un inconvénient

Une communauté réduite

Comme souvent, c'est à la fois un avantage — les gens s'entraident, les nouveaux sont bienvenus — et un inconvénient — on galère parfois pour comprendre comment ça marche, il est difficile d'obtenir des réponses très techniques, et la documentation est parfois limitée.

Toutefois, la communauté s'agrandit, d'ailleurs, vous me lisez ! M'est avis qu'un certain téléphone tactile n'est pas étranger à ce nouvel engouement.

Présentation de Cocoa

14 10 2008 In: Articles, C, Cocoa

Cet article est très important pour Cocoa.fr, car il s'agit du premier article de Renaud Pradenc, un nouveau contributeur sur le blog.

Qu'est ce que Cocoa ?

Du point de vue du programmeurs, Cocoa est un ensemble de classes, écrites en langage Objective-C. Certains vous diront que Cocoa sert à créer des interfaces graphiques. Pas seulement! Cocoa permet de créer des applications de tout type, même en ligne de commande. Elle est en fait constituée de trois parties.

Cocoa = Foundation + AppKit + CoreData

Foundation est un ensemble de classes liées aux bas niveaux: gestion des types de données (chaînes, dates, tableaux, dictionnaires…), des fichiers, des connections réseau, etc.

AppKit est la partie plus connue, dédiée à la gestion des interfaces utilisateur. C'est là que se trouvent les boutons, menus et fenêtres.

CoreData est la plus récente, puisqu'elle fut introduite avec le système 10.4. Elle sert à définir une base de données pour gérer la rétention des données.

Voilà ce qu'est Cocoa. Ni plus, ni moins. Il existe d'autres bibliothèques de classes écrites en Objective-C : je pense au récent QT kit, par exemple, ou au wrapper pour mySQL. Il faudra aussi parfois utiliser les API écrites en langage C, c'est en gros ce que l'on nomme Carbon par chez nous. Ce n'est pas sale !

Interface Builder

On pourrait dire que cette application fait partie intégrante de Cocoa, puisqu'elle sert à générer les fichiers .nib qui décrivent l'interface graphique. Quand vous découvrirez le principe des targets/actions, la proximité de Cocoa et Interface Builder vous seront évidentes.

À ce propos: Cocoa est faite pour utiliser les .nib. Il faut les utiliser, si, si ! Beaucoup de nouveaux venus (souvent formés à l'école Java et cette horreur de Swing) veulent absolument coder l'interface graphique. Sachez que l'on peut. Mais sérieusement: coder les interfaces à la mano, c'est la préhistoire; même sur mon Atari, j'utilisais un éditeur de ressources. Préférez les .nib, c'est beaucoup plus simple, beaucoup plus flexible, beaucoup moins long.

Et au niveau du langage ?

Je ne vais pas y aller par quatre chemin: Cocoa fut écrite en Objective-C, c'est le langage le plus adapté à Cocoa. Il existe ce qu'on appelle des bridges qui permettent d'interfacer Cocoa avec d'autres langages: Java, Python, Ruby, Eiffel, et un tas d'autres. Je ne peux toutefois vous conseiller des les utiliser sans avoir une connaissance de base du couple Cocoa/Objective-C. Cocoa s'appuie sur les mécanismes et conventions de ce langage, et utiliser ces bridges revient à penser en Objective-C et écrire avec la syntaxe de votre langage habituel.

Apple promet qu'on peut apprendre Objective-C en une demi-journée (quand on connaît le langage C et un langage objet): je peux témoigner que c'est vrai. Il ne reste plus ensuite qu'à apprendre Cocoa… ce qui vous prendra des mois ! Ne focalisez donc pas trop sur le langage. Objective-C a certes une syntaxe particulière — faite de crochets dans tous les sens — mais je vous promets qu'elle n'est pas si mauvaise que ça. J'y reviendrai dans un prochain article.

En attendant, n'hésitez pas à laisser vos questions et remarques dans les commentaires.

Interview de Patrick Geiller, auteur de JSCocoa

14 10 2008 In: Cocoa, Interview

Une deuxième interview sur Cocoa.fr et il s'agit cette fois ci de Patrick Geiller, l'auteur de JSCocoa.

Lire la suite