L'actualité de la WWDC 2009

03052009 Dans: Conférences

Je suis de retour après pas mal de problème de serveur et nous allons aujourd'hui voir l'actualité de la WWDC 2009 :

  • Je vous rappelle que si vous voulez soumettre une applications pour l'Apple Design Awards, la date limite de soumission est le 4 mai, c'est à dire demain.
  • Si vous pensiez aller à la WWDC et que vous n'avez pas encore votre billet, c'est trop tard, car toutes les places ont été vendues. La seul solution reste maintenant de gagner une place à l'Apple Design Awards.

Nouveau serveur

22042009 Dans: Cocoa.fr

Si vous voyez ce billet, c'est que vous êtes bien sur le nouveau serveur de Cocoa.fr. J'espère avec tout mes problèmes récents de serveur que le site n'aura plus d'indisponibilité dans les jours à venir.

Et toutes mes excuses pour tous ces problèmes.

Problèmes avec le serveur

16042009 Dans: Cocoa.fr

J'ai actuellement pas mal de problème avec le serveur qui héberge le site Cocoa.Fr et je tiens à m'excuser de toutes ces coupures. Je vais certainement assez rapidement migrer Cocoa.fr vers un autre serveur pour éviter ce genre de problèmes.

Encore désolé pour le désagrément.

Les sessions de la WWDC 2009

15042009 Dans: Conférences

Apple vient de rendre disponible la liste des conférences qui auront lieu lors de la WWDC 2009 et on peut dire qu'il y a vraiment du choix avec au total 80 conférences différentes abordant le Mac et l'iPhone. On notera tout particulièrement les conférences suivantes qui risquent d'être très intéressantes :

  • Apple Push Notification Service
  • Cut, Copy, Paste, and Undo on iPhone
  • Peer to Peer Networking with Game Kit
  • Programming With Blocks and Grand Central Dispatch
  • et plein d'autres...

Je vous invite donc à découvrir la liste des sessions : Sessions & Labs

Générateur d'images fractales (9)

14042009 Dans: Pas à pas

Quand on zoome on avant, notre ensemble fractal n'est plus très détaillé. Nous allons ajouter le réglage du nombre maximal d'itérations.

Modification de la couche Modèle

Jusqu'à présent, le nombre maximal d'itérations était codé en dur:

#define MAX_ITERATIONS  18

Nous remplaçons cette définition par la variable d'instance maxIterations

@interface CFRMandelbrotRender : NSObject {

            …
    unsigned char maxIterations; 
}

Je l'ai typée en unsigned char, pour qu'elle soit comprise entre 0 et 255. En effet, notre bitmap en 256 niveaux de gris ne saurait de toute façon pas stocker l'image avec plus de précision. Inutile donc de calculer plus de 255 itérations. Cependant, ce paramètre étant réglable par binding, il va être accédé par Key-Value Coding, qui ne gère que les entiers signés. J'ai donc rusé en utilisant des int pour les accesseurs:

- (void) setMaxIterations:(int)iterations
{
    if(iterations > 255)
        NSLog(@"-[CFRMandelbrotRender setMaxIterations:].
Le nombre d'itération doit être <= 255.");
    maxIterations = iterations;
}

- (int) maxIterations
{
    return maxIterations;   
}

On n'oublie pas de l'initialiser dans la méthode -init:

maxIterations = 18;

J'ai conservé cette valeur de 18 par défaut.

Ajout des contrôles

Ouvrez MyDocument.nib. Ajoutez à la fenêtre un NSLabel, un NSSlider et un NSTextField.

Edition du NIB

Réglez-les (avec le troisième onglet de l'Inspecteur) pour qu'ils restent scotchés au coin supérieur droit.

Configuration du NSSlider

  • Réglez son minimum à 3
    moins de trois itérations ne procure pas un résultat intéressant.
  • Réglez son maximum à 255
  • J'ai réglé Current à 10
    Peu importe, une fois bindé, il prendra la valeur par défaut du modèle, soit 18.

Configuration du NSTextField

  • J'ai tapé la valeur 255 dedans… pour m'assurer qu'elle y rentre bien.
  • Glissez un NSNumberFormatter sur le champ éditable.
    Réglez ses contraintes: minimum à 3 et maximum à 255. Décochez Allows Float, nous ne voulons que des valeurs entières.

Binding

Contrôleur

Tout d'abord, pour binder, il nous faut un objet Contrôleur qui soit compatible avec les bindings. Comme nous gérons une seule instance du Modèle, nous utiliserons un NSObjectController:

  • Glissez un NSObjectController dans MyDocument.nib
  • Renommez-le en MandelbrotRenderController.
  • Dans le premier onglet de l'inspecteur, réglez Class Name à CFRMandelbrotRender.
  • En maintenant la touche Contrôle appuyée, tirez son l'outlet content vers l'instance de Mandelbrot Render (le cube bleu).

Binding du NSSlider

Sélectionnez le slider et passez sur le 4ème onglet de l'Inspecteur ("Bindings"). Pour binder la clé Value:

  • Bind to: MandelbrotRenderController
  • Controller Key = selection
  • Model Key Path = maxIterations

Binding du NSTextField

Bindez le text field exactement de la même façon.

Résultat

Vous pouvez maintenant lancer le programme. Glissez le curseur Itérations maximales: l'ensemble reste le même. Allez sur la vue, et déplacez le repère ou zoomez: enfin, la nouvelle valeur est prise en compte.

Ce qui se passe est que le binding modifie effectivement maxIterations dans le CFRMandelbrotRender, mais cela ne provoque ni le recalcul de l'ensemble, ni l'affichage du nouvel ensemble.

Observation

Il faut un moyen pour que la vue sache que les paramètres ont été modifiés, que l'ensemble doit être recalculé, puis la vue rafraîchie. Une technique pourrait être de relier les actions du NSSlider et du NSTextField à la vue. Cependant, je pense ajouter par la suite des NSTextField pour permettre l'édition des autres paramètres, et cela va commencer à faire beaucoup d'actions. C'est pourquoi nous utiliserons ici la technique plus sophistiquée du Key-Value Observing.

Signaler le besoin d'une mise à jour

L'idée est que le CFMandelbrotRender sait quand il doit être recalculé: dès qu'un de ses paramètres de calcul est modifié. Nous allons lui ajouter une variable d'instance besoinMAJ, indiquant qu'une mise à jour est nécessaire:

@interface CFRMandelbrotRender : NSObject {

            …

    BOOL    besoinMAJ;  // Indique qu'une mise à jour est nécessaire

}

Ensuite, dès qu'un paramètre de calcul est modifié, nous mettrons besoinMAJ à YES:

- (void) setLargeurBitmap:(NSUInteger)largeurPixels
{
    largeurBitmap = largeurPixels;

    [self willChangeValueForKey:@"besoinMAJ"];
    besoinMAJ = YES;
    [self didChangeValueForKey:@"besoinMAJ"];

}

Notez l'encadrement par willChangeValueForKey: et didChangeValueForKey:. Ceux-ci sont indispensables au Key-Value Observing pour savoir que la variable besoinMAJ a changé.

Il faut faire de même dans les méthodes setHauteurBitmap:, zoomerDuFacteur:, decalerCentreX:y: puisqu'on y modifie les paramètres de calcul. Pour cette même raison, modifiez le setter de maxIterations:

- (void) setMaxIterations:(int)iterations
{
    if(iterations > 255)
        NSLog(@"-[CFRMandelbrotRender setMaxIterations:]. Le nombre d'itération doit être <= 255.");
    maxIterations = iterations;

    [self willChangeValueForKey:@"besoinMAJ"];
    besoinMAJ = YES;
    [self didChangeValueForKey:@"besoinMAJ"];
}

À la fin du rendu, repositionnez la variable:

- (NSBitmapImageRep*) bitmapImageRep
{
            …

    [self willChangeValueForKey:@"besoinMAJ"];
    besoinMAJ = NO;
    [self didChangeValueForKey:@"besoinMAJ"];

    return bitmapRep;
}

Observer les besoins de mise à jour

Passons maintenant à la vue.

Contexte

Créons d'abord un contexte. De quoi s'agit-il ? D'objets uniques qui permettent d'identifier quel keypath a changé par une rapide comparaison de pointeurs, plutôt qu'une lente comparaison de chaînes de caractères:

static void* ContexteMAJRendu = (void*) @"ContexteMAJRendu";

Le contenu de la chaîne n'a aucune importance, puisque c'est le pointeur de l'objet que nous allons utiliser. On utilise habituellement une chaîne parce que c'est plus simple pour le débogage, mais n'importe quel autre objet peut faire l'affaire, pourvu que son pointeur soit unique.

Changements

Pour être tenu au courant des changements des clés observées, implémentons la méthode:

- (void)observeValueForKeyPath:(NSString *)keyPath
    ofObject:(id)object
    change:(NSDictionary *)change
    context:(void *)context
{
    if(context == ContexteMAJRendu)
    {
        [self setNeedsDisplay:YES]; 
    }

}

Nous identifions le contexte et demandons l'affichage de la vue le cas échéant. Pour l'instant, il n'y a qu'une variable à observer, donc qu'un seul contexte, mais ça peut évoluer.

Nous n'avons plus besoin d'appeler setNeedsDisplay: ailleurs. Retirez-le des deux autres endroits.

Commencer l'observation

Ajoutez la méthode:

- (void) awakeFromNib
{
    [render addObserver:self forKeyPath:@"besoinMAJ" options:0 context:ContexteMAJRendu];   
}

Elle est appelée dès que tous les objets du NIB sont prêts. En particulier, ici, c'est l'objet render qui doit l'être. Nous ajoutons un observateur (=la vue), du keyPath besoinMAJ. Nous laissons les options par défaut, et fournissons le contexte à passer lors des changements.

Arrêter l'observation

Arrêter l'observation est toujours délicat, car il faut qu'elle ait cessé avant que l'objet observé reçoive un message -[dealloc]. Nous allons le faire quand la fenêtre se ferme.

- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
    if(newWindow == nil)
        [render removeObserver:self forKeyPath:@"besoinMAJ"];
}

Cette méthode est habituellement appelée lorsque la vue est insérée dans la fenêtre. Cependant, quand newWindow est nulle, cela signifie que la fenêtre va être close.

Et là ça marche ?

Vous pouvez essayer de lancer à nouveau l'appli. Cette fois-ci, ça fonctionne. À la prochaine !

Le projet Xcode complet à télécharger.

Renaud Pradenc
Céroce

Parce qu'il est toujours intéressant de garder une certaines ouvertures sur ce qui est disponible ailleurs, j'ai décidé de faire un petit comparatif rapide entre les principales plates-formes mobile. Je vous parlerais donc ici de Android, Palm Mojo et bien sur l'iPhone OS (dont la version 3 est très prometteuse) :

  • Android, le système d'exploitation mobile selon Google, est actuellement utilisé sur deux téléphones HTC. Il s'agit d'un système d'exploitation basé sur Linux et donc le développement d'applications s'effectue en Java. Toute la documentation concernant le développement est disponible sur Android Developers et point très important, le kit de développement (SDK) Android est disponible sur Mac OS X, Linux et Windows, ce qui permet au plus grand nombre de l'installer et de développer pour ce système.
  • Palm Mojo, est le système d'exploitation sensé marquer le renouveau dans Palm dans le domaine. Il s'agit d'un OS dont les applications sont développés avec les langages HTML, CSS et Javascript, ce qui explique que Palm l'appel aussi Web OS. On ne sait pour l'instant pas grand chose sur cet OS, et l'inscription pour avoir accès au kit de développement à commencé le 1er avril, ce qui est donc très récent. Comme pour le kit Android, le SDK Palm Mojo sera disponible sur Mac OS X, Linux et Windows. Pour plus d'informations, je vous invite à lire le premier chapitre du livre Palm® webOS: Developing Applications in JavaScript Using the Palm MojoT Framework disponible gratuitement en ligne.
  • iPhone OS, dont j'ai déjà pas mal parlé sur le blog, je vous invite donc à lire les anciens billets concernant l'iPhone. On pourra tout de même signaler que contrairement à ses concurrents, le SDK de l'iPhone OS ne fonctionne que Mac OS X, ce qui le rend inaccessible à tous les développeurs travaillant sous Linux ou Windows.

D'autres systèmes existent comme Symbian sur les téléphones Nokia ou BlackBerry sur les téléphones du même nom, mais il n'existe pas sur ces téléphones une communauté de développeurs aussi active que celles disponible pour l'iPhone OS ou Android. C'est donc pour ça que je ne les ai pas traité ici.

Espérons que toutes cette agitation et cette concurrence soit bénéfique pour nous et pousse Apple à écouter ses développeurs et à faire évolution l'iPhone OS.

Mais que mettre dans les menus contextuels ?

06042009 Dans: Design

L'un des béta-testeurs de mon logiciel m'a posé une question intéressante: "À quand les menus contextuels ?". Ce à quoi j'ai répondu: "Jamais !".
Comment puis-je donner une réponse aussi catégorique ? Parce que cela fait un moment que j'y réfléchis.

Une demande des switchers

Les menus contextuels sont apparus sous Mac OS 8.5, alors que jusqu'alors, Apple ne les avait pas trouvés nécessaires. Il s'agissait de répondre à une demande des utilisateurs venant du monde Windows, qui ne parvenaient pas à créer un dossier ou faire du copier-coller.

Sous NeXTStep

Je souhaite revenir à ce vieux système, parce qu'il a poussé les menus contextuels très loin. D'après ce que je me suis laissé dire, un clic droit y permettait d'afficher un menu proposant toutes les opérations possibles sur l'objet cliqué, présentées en menus hiérarchiques. Et ce fonctionnement n'était pas affreux, puisqu'il était cohérent: on était sûr d'y trouver toutes les opérations possibles.

Il n'était pas non plus idéal, parce que les menus hiérarchiques ne sont jamais très pratiques: la souris a tendance à replier trop facilement le menu, et puis quand on arrive sur le bord droit de l'écran, l'article de menu doit passer à la ligne; on s'y perd un peu.

Pendant ce temps là, chez Microsoft

Sur PC, on était habitué depuis longtemps à ce que la souris comporte souvent trois boutons. Seules les applications de CAO en tiraient parti; pour le reste, comme l'IHM de Windows avait été pompée sur le Mac, Microsoft s'est longtemps demandé que faire des boutons supplémentaires, qui servaient à faire défiler le document ou à émuler le double-clic. Quand ils se décidèrent à utiliser le bouton droit pour faire apparaître un menu contextuel, ils ne voulurent pas — comme nous l'avons vu, par commodité — proposer trop de menus hiérarchiques, mais limitèrent la liste des opérations à une poignée.

Ceci amena alors une question: quelles opérations incorporer ?

Revenons au Mac

Tout développeur se retrouve donc avec la même question que Microsoft. Comme chez Apple, ils sont balèzes et que ça fait dix ans que ça existe sur Mac, ils ont dû trouver la réponse, pas vrai ? Comme à mon habitude, je m'en vais lire la bible, et la confronter aux logiciels d'Apple:

Un petit exemple sous Safari:

Copie d'écran de Safari

Et un extrait des AHIG:

Include a small subset of the most commonly used commands in the appropriate context. For example, Edit menu commands should appear in the contextual menu for highlighted text, but a Save or a Print command should not.

Un autre exemple sous Finder:

Copie d'écran de Finder

Always ensure that contextual menu items are also available as menu commands. A contextual menu is hidden by default and a user might not know it exists, so it should never be the only way to access a command. In particular, you should not use a contextual menu as the only way to access an advanced or power-user feature.

Ma démarche n'est pas de démontrer qu'Apple — qui n'est pas à une contradiction près — ne suit pas les règles qu'elle édicte; simplement que ses ingés ne savent foutrement pas quoi mettre dans ces menus.

C'est pas tout ça, mais j'ai un logiciel à coder

Je ne saisis pas bien l'intérêt d'avoir une manière supplémentaire de faire du copier-coller, dont les raccourcis-clavier sont bien connus. En tant qu'utilisateur, j'utilise les menus contextuels, mais justement pour les fonctionnalités avancées.

Et pour une application aussi simple que la mienne — il n'y a même pas de Préférences — je peux dire que les menus contextuels ne sont pas pour demain.

Renaud Pradenc
Céroce

Apple vient d'annoncer son projet d'abandonner le langage Objective-C en faveur de Java pour un certain nombre de raisons :

  • Il est nettement plus facile de trouver des développeurs Java que des développeurs Objective-C.
  • Java est le seul vrai langage pour écrire des applications Enterprise
  • La compatibilité des application iPhone avec les applications Android (qui utilise déjà Java).

Le SDK iPhone devrait donc rapidement apparaître dans une nouvelle version permettant l'utilisation de Java, et d'après les rumeurs, une version 4.0 de XCode basé sur Eclipse devrait être remise aux développeurs lors de la WWDC 2009.

En vrac : iPhone

30032009 Dans: En vrac

Après quelques jours avec peu de publication sur Cocoa.fr, voici un billet particulièrement fourni pour la série En vrac. On commence par un coup de gueule et une interview de Cyril, le développeur de iCompta et iComptaMobile :

Les articles suivants sont aussi très intéressant :

Et pour les personnes intéressées par des articles plus technique, je vous invite à lire :

Pour finir, vous trouverez sur le MacDev Network un retour sur le dernier livre concernant de développement Mac de The Pragmatic Programmers :

WWDC 2009 : du 8 au 12 juin

26032009 Dans: Conférences

Apple vient d'annoncer les dates de l'édition 2009 de la WWDC, et elle aura lieu du 8 au 12 juin au Moscone Center de San Francisco. Elle proposera aux développeurs de suivre diverses conférences concernant l'iPhone et Mac OS X et de rencontrer les ingénieurs Apple.

Elle a eu lieu l'année dernière à guichet fermé, il y a donc de fortes chances que les places partent très vite à nouveau cette année. Pour en savoir plus et s'inscrire :


Sponsors