Cocoa (Apple)

interface de programmation

Cocoa est une API native d'Apple pour le développement orienté objet sur son système d'exploitation Mac OS X. C'est l'une des cinq API majeures disponibles pour Mac OS X, les autres étant : Carbon, la boîte à outils Macintosh (pour l'environnement obsolète Classic), POSIX (pour l'environnement BSD) et Java. Certains environnements, comme Perl et Ruby sont considérés comme mineurs, car ils n’ont pas accès à toutes les fonctionnalités et ne sont généralement pas utilisés pour le développement d'applications à part entière.

Les applications Cocoa sont typiquement construites en utilisant les outils de développement fournis par Apple, Xcode (anciennement Project Builder) et Interface Builder, en utilisant les langages de programmation Objective-C et Swift. De plus, l'environnement de programmation Cocoa peut être accessible en utilisant d'autres outils, comme Ruby (via MacRuby (en) et RubyMotion (en)) et C# (via Xamarin). Il est aussi possible d'écrire un programme Objective-C Cocoa dans un simple éditeur de texte et de le compiler par la suite avec GCC ou en utilisant les scripts makefile de GNUstep.

Pour l'utilisateur final, les applications dites Cocoa sont considérées comme étant celles écrites en utilisant l'environnement de programmation Cocoa. Habituellement, ces applications ont un ressenti différent dû à l'automatisation d'une multitude d'aspects de l'application par l'environnement Cocoa. Ceci est ainsi fait pour suivre la politique de développement d'Apple.

Au fil des versions de Mac OS X, on assiste à un rapprochement progressif de Cocoa et de Carbon, construits de plus en plus à partir de la même base (Core Foundation (en)). Certaines applications Carbon, tirant parti des nouvelles fonctionnalités de Mac OS X, ne fonctionnent plus sous Mac OS 9 et la limite se fait de plus en plus floue. Il est rare de trouver des applications Cocoa qui ne font aucun appel à l’API Carbon.

L'histoire de Cocoa

modifier

Cocoa est dérivé des environnements de développement NeXTSTEP et OPENSTEP créés par NeXT à la fin des années 1980. Apple acquit NeXT en et commença par conséquent à travailler sur le système d'exploitation Rhapsody, supposé être le successeur direct d'OPENSTEP. Ce dernier devait avoir un système d'émulation pour les applications macOS, appelé Blue Box. Et par opposition à ce système d'émulation, les bibliothèques et les objets binaires de bases dérivés d'OPENSTEP furent au contraire appelés Yellow Box. Rhapsody évolua finalement vers Mac OS X et la Yellow Box devint Cocoa. C'est ainsi que les classes Cocoa commencent toutes par le préfixe « NS » (représentant soit la création d'OPENSTEP par l'association NeXT-Sun, soit NeXTSTEP, le framework propriétaire de NeXT pour OPENSTEP[1]) : NSString, NSArray, etc.

Une grande part du travail fourni pour développer OPENSTEP fut réutilisé dans le développement de Mac OS X, Cocoa étant la partie la plus visible. Il y a néanmoins plusieurs différences entre la Yellow Box et Cocoa. Par exemple, NeXTSTEP et OPENSTEP utilisaient PostScript pour l'affichage à l'écran de textes et d'images, tandis que Cocoa dépend de Quartz (qui utilise les composants PDF pour l'imagerie). Cocoa dispose aussi, dans une certaine mesure, du support de l'internet, comprenant entre autres les classes NSURL et WebKit HTML, tandis qu'il n'y avait qu'un support rudimentaire des systèmes réseaux sous OPENSTEP, par l'intermédiaire des classes NSFileHandle et des Berkeley sockets.

Avant d'être ce que l'on connaît, Cocoa était le nom d'une application permettant aux enfants de créer des projets multimédias. Cette application, originellement connue sous le nom de KidSim (en), est désormais accréditée par une entreprise tierce nommé StageCast et est vendue sous le nom de Stagecast Creator (en). Le développement de ce programme fut arrêté après le retour de Steve Jobs chez Apple et le nom « Cocoa » fut réutilisé pour éviter le délai dû à l'enregistrement d'une nouvelle marque. StageCast accepta par la suite de vendre l'ancien Cocoa sous un nouveau nom.

Gestion de la mémoire

modifier

Une des fonctionnalités importantes de l'environnement Cocoa est sa facilité pour gérer la mémoire allouée dynamiquement. La classe NSObject de Cocoa, de laquelle la plupart des classes sont dérivées, implémente un compteur de référence pour la gestion de la mémoire. Les objets dérivés de la classe racine NSObject répondent à des messages de rétention (retain) et de libération (release). Un nouvel objet alloué dérivant de NSObject créé avec alloc ou copy dispose d'un compteur de retiens dont la valeur est de un. Envoyer à cet objet un message de retiens provoquera l'incrémentation de son compteur, tandis qu'envoyer un message de libération décrémentera son compteur. Lorsque le compteur de retiens d'un objet atteint zéro, ce dernier est désalloué et sa mémoire est libérée (la désallocation est aux objets Objective-C, ce que la destruction est aux objets C++. La méthode dealloc est similaire à un destructeur en C++.) Cette approche pour la gestion de la mémoire est très similaire au COM développé par Microsoft.

En plus de la comptabilisation manuelle des références, les développeurs peuvent choisir l'utilisation de plusieurs autorelease pools (que l'on pourrait traduire par « réserves d'auto-libération »). Envoyer le message autorelease à un objet va l'enregistrer, en vue d'une future libération, dans l’autorelease pool la plus proche de son processus. Lorsque l’autorelease pool est elle-même libérée, elle envoie à toutes les classes enregistrées le message de libération correspondant. Ces « réserves de libération » sont souvent créées puis libérée au début et à la fin d'une boucle d'événement, garantissant que, durant l'exécution, le programme a achevé avec succès le bloc d'instruction où les objets étaient auto-libérés. En d'autres termes, les performances de l'application sont plus prévisibles et la gestion de la mémoire est totalement transparente pour l'utilisateur. Ceci se démarque nettement des systèmes de gestion automatiques de la mémoire où, dans la plupart des cas, l'application va parfois se bloquer soudainement lors de la mise en route du ramasse-miettes.

Néanmoins, un ramasse-miettes automatique existe également pour Cocoa. Ce dernier est disponible sous Objective-C 2.0, en utilisant Xcode 3.0 inclus dans Mac OS X 10.5 Leopard. Le programmeur a désormais le choix de gérer manuellement la mémoire ou non. À ce sujet, les avis sont divisés. Certains disent[Qui ?] que la comptabilisation des références est supérieure car elle permet au développeur d'accéder à un contrôle précis sur certains objets à désallouer, tout en n'ajoutant pas la charge de devoir inspecter chaque objet que le programme désalloue. Par ailleurs, la baisse de performances habituellement imputée aux ramasse-miettes automatiques est ici très négligeable. En revanche, d'autres disent que ce système est inutile puisqu'un ramasse-miettes automatique semblable à celui proposé par Java est supérieur, simplement parce que ce dernier réduit les erreurs dues au programmeur dans la gestion de la mémoire. Dans Cocoa, le ramasse-miettes automatique peut être utilisé ou non, en fonction des préférences du projet. De plus, il peut être activé ou désactivé à différents points du programme. Le ramasse-miettes automatique est déprécié depuis Mac OS X 10.8, Apple préconise le comptage de référence automatique ARC (en) introduit avec Mac OS X 10.7.

Framework principal

modifier

Cocoa est principalement constitué de trois bibliothèques Objective-C appelées frameworks. Les frameworks sont similaires en fonctionnalité aux bibliothèques partagées — un objet compilé qui peut être dynamiquement chargé dans une adresse mémoire du programme pendant l'exécution — mais les frameworks offrent aussi des ressources liées, des fichiers d'en-tête, ainsi qu'une documentation fournie.

  • Foundation Kit (en), ou plus simplement Foundation est apparu pour la première fois dans OpenStep. Sur Mac OS X, il est basé sur Core Foundation (en). Foundation est une bibliothèque orientée objet générique, fournissant des outils de manipulations de chaîne de caractères, de valeurs numériques ou encore diverses structures de données. Des outils pour le calcul distribué et les boucles événementielles ainsi que des fonctionnalités indirectement liées à l'interface graphique utilisateur sont aussi proposée par Foundation.
  • Application Kit (en) ou AppKit est directement hérité de l'original NeXTSTEP Application Kit. Il contient du code permettant de créer et d'interagir avec les interfaces graphiques utilisateurs. AppKit est construit comme une sur-couche de Foundation et utilise par conséquent le même préfixe « NS ».
  • Core Data (en) ou frameworks de persistance, il facilite l'enregistrement des objets dans un fichier, et par la suite leur chargement en mémoire.

Une partie clef de l'architecture Cocoa est son modèle de visualisation complet. L'organisation, bien que réalisée de façon conventionnelle pour un framework application, est basée sur le modèle de dessin PDF fourni par Quartz. Ce modèle permet la création de contenu dessiné personnalisé en utilisant des commandes de dessin dans le style PostScript, ce qui implique aussi une prise en charge automatique de l'impression. Par ailleurs, depuis que le framework Cocoa se charge du cadrage, de la taille ou du déplacement d'objets graphiques, ainsi que d'autres tâches inhérentes à la création de ces objets, le programmeur n'a plus besoin d'implémenter ces fonctionnalités basiques et peut se concentrer uniquement sur les fonctionnalités propres à son application.

Modèle-Vue-Contrôleur

modifier

À la fin des années 1970, l'équipe Smalltalk travaillant à Xerox PARC instaura une méthode de conception menant à un développement aisé tout en maximisant la réutilisation du code. Appelé « Modèle-Vue-Contrôleur » (MVC), le concept sépare une application en trois couches distinctes interagissant entre elles. Les classes modèles représentent les données pures comme des documents, des fichiers de configuration ou des objets en mémoire. Les vues sont, comme leur noms l'indiquent, des représentations (souvent visuelles) des données. Les classes contrôleur lient les modèles avec leur(s) vues respectives et les maintiennent synchronisées.

L'architecture de Cocoa est une application stricte des principes MVC. Sous OpenStep, la plupart des classes fournies était soit des vues de haut-niveau, soit des classes modèles de bas-niveau comme NSString. Comparé à des systèmes MVC similaires, OpenStep souffrait de l'absence d'une vraie couche modèle. Il n'y avait pas de classes pour stocker et représenter un « document » par exemple. Ainsi, pendant la transition vers Cocoa, la couche modèle fut grandement étendue, introduisant un certain nombre de classes pre-intégrées fournissant des fonctionnalités basiques aux applications de bureau.

Dans Mac OS X 10.4, Apple introduisit la famille de classe NSController, fournissant des comportements prédéfinis à la couche contrôleur. Ces classes sont considérées comme une partie du système Cocoa binding, faisant une utilisation étendue des protocoles, comme le Key-Value Observing et Key-Value Binding. Le terme binding réfère à la relation entre deux objets, principalement entre une vue et un contrôleur. Les bindings permettent au développeur de se concentrer plus sur la mise en relation des objets plutôt que sur la planification de leur comportement.

Avec l'arrivée de Mac OS X 10.4, Apple élargit Foundation en introduisant le framework Core Data (en), qui standardisa le suivi des changements et la rémanence dans le modèle. En réalité, ce framework simplifie grandement les changements fait aux applications, l'annulation de ces changements (si nécessaire), la sauvegarde des données sur le disque et enfin la relecture de ces dernières.

En fournissant ce framework pour les trois couches MVC, le but d'Apple est de réduire la quantité de code glue que les développeurs avaient à écrire pour maintenir la cohésion du programme, leur permettant ainsi de passer plus de temps sur les fonctionnalités spécifiques de leurs applications.

Association tardive

modifier

Dans la plupart des langages orientés objets, l'appel aux méthodes est représenté physiquement par un pointeur vers le code en mémoire. Ceci restreint le développement d'applications surtout lorsque des classes de « traitement de commande » sont requises. Elles sont habituellement organisées selon le motif de conception dit de chaîne de responsabilité. Bien que Cocoa utilise cette approche la plupart du temps, l'association tardive d'Objective-C permet d'avoir une plus grande flexibilité.

Sous Objective-C, les méthodes sont représentées par un sélecteur, qui est une chaîne décrivant la méthode à appeler. Lorsqu'un message est envoyé, le sélecteur est envoyé dans l'environnement d'exécution Objective-C. Il est ensuite mis en correspondance avec une liste de méthodes disponibles pour finalement appeler l’implémentation correcte de la méthode. Depuis que le sélecteur est une donnée texte, il est devenu possible de le sauvegarder dans un fichier, de le transmettre sur un réseau ou entre deux processus, ou encore de le manipuler plus facilement. L'implémentation des méthodes est analysée durant l'exécution et non pendant la compilation. Il y a bien sûr une légère baisse de performance[2], mais l'association tardive permet à un même sélecteur de pointer vers différentes implémentations.

De la même manière, Cocoa fournit une technique de manipulation de données omniprésente appelée key-value coding (KVC). Elle permet, pour une portion de données ou une propriété d'un objet, d'être recherché ou changé pendant l'exécution grâce à son nom (le nom de la propriété agit comme une clé pointant vers la valeur elle-même. Dans les langages traditionnels, cette association tardive est impossible. Mais KVC mène vers une grande flexibilité de conception). Le type d'un objet n'a pas besoin d'être connu, de même qu'aucune propriété de cet objet peut être découverte en utilisant KVC. De plus, en développant avec ce système, grâce à ce que Cocoa appelle Key-Value Observing (KVO), un support automatique pour l'annulation et la restauration d'action est fourni.

La puissance des objets

modifier

Une des fonctionnalités les plus utiles de Cocoa est la présence d'« objets de base ». Par exemple, les classes de base NSString et NSAttributedString qui fournissent des chaînes de caractères Unicode et le système NSText dans AppKit qui permet au programmeur de placer des chaînes de caractères dans le GUI.

NSText, ainsi que ses classes parentes, sont utilisées pour afficher et éditer des chaînes de caractères. Cette collection d'objets permet, dans une application, d'implémenter quasiment n'importe quoi. Les implémentations possibles vont d'un simple champ de saisie à un document complet multi-page, avec des fonctionnalités typographiques professionnelles, comme le kerning, les ligatures, la mise en page non linéaire, les rotations, le support de l'Unicode ou encore un rendu anti-aliasé des caractères. La mise en page des paragraphes peut être contrôlée automatiquement ou manuellement, en utilisant une « règle » pouvant être attachée à toute portion de texte. La correction orthographique est automatique, par l'intermédiaire d'un simple dictionnaire utilisé par toutes les applications exploitant le soulignage des erreurs introduit par Microsoft (une ligne en pointillé est utilisée dans Cocoa). Un support de l'annulation et de la restauration des actions (Undo/Redo) illimité est intégré. En utilisant seulement les fonctionnalités pré-intégrées, n'importe qui peut écrire un éditeur de texte sans pratiquement aucune ligne de code. D'ailleurs, avec les nouveaux objets contrôleur, le nombre de lignes de code pourrait bien atteindre zéro. Ceci contraste nettement avec les API de TextEdit existant auparavant dans Mac OS.

Lorsque des extensions sont requises, l'utilisation par Cocoa d'Objective-C facilite l'implémentation de ces extensions. Objective-C inclut le concept de « catégories » qui tient compte des modifications d'une classe existante déjà mise en place. Les fonctionnalités peuvent être incorporées dans une catégorie sans changer quoi que ce soit de la classe originale du framework, ni même accéder à ses sources. Sous la plupart des frameworks habituels cette tâche demanderait au programmeur de créer une nouvelle sous-classe comportant les fonctionnalités additionnelles, puis de remplacer toutes les instances de l'ancienne classe par celles de la nouvelle.

Implémentations

modifier

Le framework Cocoa est écrit en Objective-C, par conséquent Objective-C est le langage préféré pour le développement d'applications Cocoa. Les bindings Java pour le framework Cocoa (connus comme le « Java bridge ») sont aussi disponibles, mais n'ont jamais été très populaires chez les développeurs Cocoa. En outre, le besoin de binding pour l'environnement d'exécution Java implique que beaucoup de fonctionnalités clés de Cocoa ne sont pas disponibles avec Java. En 2005, Apple annonça que le « Java bridge » était devenu obsolète et était désormais à éviter, impliquant que les nouvelles fonctionnalités ajoutées dans Cocoa par la suite (à partir de Mac OS X 10.4) ne seraient pas ajoutées dans l'interface de programmation Cocoa-Java.

AppleScript Studio, faisant partie des outils Xcode d'Apple rend possible l'écriture d'applications Cocoa (moins complexes) en utilisant AppleScript. Il existe aussi un langage de scripts tiers, crée spécifiquement pour Cocoa, appelé F-Script, qui permet un accès natif aux objets Cocoa et qui fournit une suite d'outils graphiques.

Les bindings sont aussi disponibles pour d'autres langages :

Une liste des implémentations plus exhaustive est disponible.

Il existe aussi des implémentations open source d'une grande partie du framework Cocoa permettant un développement multiplateforme (incluant Windows) d'applications Cocoa :

Références

modifier

Liens externes

modifier