Archives

Archives pour la catégorie ‘Développement’

Présentation de Xcode 4

1 août 2011

Depuis très longtemps, pour développer des applications Mac, il fallait utiliser deux outils distincts : Interface Builder et Xcode. Le premier, comme son nom l’indique très bien, permet de construire des interfaces graphiques : c’est un outil visuel, dans lequel on crée des interfaces en y plaçant des objets par glisser/déposer et en définissant les propriétés de ces objets. Xcode, lui, c’est l’éditeur de code, principalement Objective-C, C et C++.

Les deux outils étaient séparés et il fallait souvent faire des allers-retours entre les deux durant la phase de création de l’interface d’une application. Chacun de ces deux logiciels disposaient de plusieurs fenêtres, et il était assez facile de ne plus s’y retrouver.

Et puis l’iPhone est arrivé ! Et surtout l’App Store, qui permet à tout développeur de vendre son application, sur un fabuleux marché de plusieurs millions d’utilisateurs. Pour développer une application iPhone, on passait par les mêmes outils : Interface Builder et Xcode. Pour un développeur habitué à des outils comme Eclipse (ou autre Visual Machin-Truc), il faut avouer que la transition ne se faisait pas sans douleur…

Et puis Xcode 4 est arrivé, sans son fidèle compagnon. Et pour cause : Xcode a complètement absorbé Interface Builder ! Les deux ne font plus qu’un. Apple a sans doute voulu rapprocher son outil de développement intégré (IDE) des autres outils pour faciliter la transition depuis d’autres environnements, et aussi pour attirer encore plus de développeurs sur sa plate-forme. Et je dois dire que ce changement me convient très bien :)

En attendant des tutoriels plus développés, je vous propose quelques captures d’écran annotées de ce nouveau Xcode !

Développement

OnliGence : bientôt un nouveau produit tout droit sorti des GreenIvory’s labs

6 mai 2011

Je ne peux pas en dire plus pour l’instant, nous essayons de garder le secret sur ce que sera OnliGence. Mais je peux d’ores et déjà vous dire que ce sera un outil puissant et utile à tous !

Je fais partie de l’équipe qui le développe, pour la partie visible du produit (UI) et je peux vous dire que je l’attends avec impatience ! Mais il reste encore quelques finitions à faire…

Pour les développeurs qui me lisent, voici quelques informations techniques qui pourront vous intéresser : l’interface graphique a été développée en GWT, en utilisant activement les dernières évolutions comme MVP, Activity & Place, les ClientBundle et autres CssResource… On a mis le paquet pour faire un produit propre et joli (tant visuellement que dans le code).

En attendant, vous pourrez en découvrir davantage sur la page Facebook d’OnliGence

AnnoncesDéveloppementÉvénementsLogiciels

Mercurial : une alternative séduisante à Subversion

10 février 2011

Amis développeurs, cet article est pour vous ! Pour les non-développeurs, eh bien, je m’excuse, mais cet article risque fort de ne pas vous être d’une grande utilité (sans pour autant prétendre que mes autres articles le soient).

Tout développeur a eu un jour affaire à un système de contrôle de code source (SCM). Du moins, je lui souhaite. Parmi les plus connus et les plus répandus (je parle des SCM, pas des développeurs…), on trouve :

  • CVS, l’ancien, on se demande même s’il n’était pas là avant la Création,
  • Subversion (ou SVN), qu’on utilise quand on a franchi un pas de trop vers la folie à cause de CVS.

Mais si Subversion vous rend dingue, que vous reste-t-il ?

Peut-être bien Mercurial ! Son ambition est simple : oubliez Subversion et ses problèmes, utilisez Mercurial et retrouvez le goût pour le développement logiciel ! Hum, bon, c’est prétentieux, certes, mais d’après la description que je viens d’en lire et les concepts utilisés, cela me semble tout à fait possible. J’ai identifié deux aspects particulièrement intéressants :

  • Le commit se fait en deux phases :
    1. Le développeur commit sur son repository local et peut ainsi profiter du système de versioning (et des revert, notamment), sans pour autant impacter le reste du monde.
    2. Quand le code est stable, il push ce code sur le repository central.
  • Mercurial stocke les changements (changesets) d’une manière intelligente et est ainsi capable d’effectuer de véritables merge sans conflits. Le branchage devient alors un véritable outil de production plutôt qu’une bête noire.

Pour en savoir plus, je vous laisse lire cette très bonne introduction à Mercurial (en anglais).

Développement

eBALLution

8 décembre 2009

Cela fait déjà quelque temps que je développe un petit jeu vidéo pour Mac OS X, histoire d’apprendre quelques technologies telles que OpenGL, Cocoa… ça change de Java, HTML et CSS ! Le moteur est maintenant assez avancé pour que j’ose en parler.

Le jeu s’appelle eBALLution. C’est un casse-brique qui vous fera voyager dans le temps afin de vous faire (re)découvrir l’histoire de la vie et de l’Homme : de la création de l’Univers et de notre chère planète Terre jusqu’à la vie de tous les jours, en passant par les dinosaures, l’Antiquité, le Moyen-Âge, les grandes découvertes, … Ce jeu sera gratuit, mais j’accepterai avec plaisir les dons :-)

Le jeu a déjà son site internet, eballution.com, sur lequel je publierai des articles lors de mes grandes avancées dans le développement.

Rien n’est encore définitif, mais voici tout de même quelques images des niveaux de test déjà existants :

Je prévois de sortir une version beta pour la fin de l’année… prochaine (2010). Eh oui, ça demande du temps de confectionner et peaufiner les différents niveaux, surtout que j’en ai prévu un nombre assez important. C’est qu’il y a 13,8 milliards d’années à retracer !

AnnoncesDéveloppementLogicielsMac

Toutes les recettes des desserts de votre enfance sur votre iPhone

15 juin 2009

Application Gourmandise pour iPhoneJe ne pouvais pas trouver meilleur sujet pour mon blog : une application pour iPhone qui recense toutes les recettes des desserts de notre enfance ! J’ai nommé : Gourmandise. Oui : biscuits, tartes, crêpes, gaufres, clafoutis (le clafoutis, c’est exquis !), puddings et crumbles seront désormais toujours à portée de votre plan de travail, sur votre iPhone ou iPod Touch chéri. Le tout dans une application très bien réalisée, tant sur l’aspect visuel que fonctionnel : recherche par thème ou ingrédients, liste de courses, notation des recettes avec commentaire… Cerise sur le gâteau (très appropriée, comme expression) : vous avez envie de vous faire plaisir, mais il y a trop de bonnes recettes dans cette application : faites tourner la Roue des Desserts et laissez Gourmandise choisir à votre place ! Vous ne serez jamais déçus : les 50 recettes proposées sont toutes délicieuses. Enfin… je n’ai évidemment pas testé toutes les recettes, hein, mais rien que les photos pourront confirmer ce que je vous dis là.

L’auteur est français et je souhaite le féliciter pour cet excellent travail ! L’application est disponible sur l’AppStore pour le prix d’un kilo de sucre en poudre (1,59 €) !

Quand je vous disais en début d’article que je ne pouvais pas trouver meilleur sujet : l’auteur tient également un forum qui traite du développement d’applications sur Mac et iPhone. Eh hop !, dans un article, je parle des trois grands thèmes de mon site ! Non ? Les plus perspicaces d’entre vous se diront que cet article ne parle pas de randonnées, ce qui jusque là est vrai. Mais après avoir testé Gourmandise, ne croyez-vous pas que quelques (petites) randonnées vont s’imposer ?

DéveloppementExcursionsiPhoneLogiciels

Révision des MacBook : je vends mes Mac !

8 juin 2009

Les MacBook ont également été revus aujourd’hui : plus de puissance, lecteur de cartes SD (oui je sais, toute la concurrence le fait déjà !) et baisse des prix. Dans quelques semaines, je devrais avoir mon nouveau MacBook pro. Et je souhaite n’avoir plus qu’une seule machine.

Je vais donc revendre mon iMac 20 pouces (que pourtant j’adooore) ainsi que mon MacBook 13 pouces noir.

Mon iMac est disponible immédiatement pour environ 830 euros. Le MacBook sera disponible quand j’aurai le nouveau et terminé la migration (dans l’été, donc) pour environ 800 euros. Ces deux (superbes) machines seront entièrement ré-installées proprement avec la dernière version de Mac OS X et livrées dans leur boîte d’origine, avec tous les accessoires (télécommande, chiffon de nettoyage et DVD de Mac OS X).

Si vous êtes intéressés, ou si vous connaissez des personnes qui pourraient être intéressées, n’hésitez pas à prendre contact avec moi.

AnnoncesCocoa

Une liste déroulante qui se souvient et qui propose

6 mars 2009

Le but de cet article est de nous familiariser avec le widget NSComboBox. Il existe deux manières de peupler une liste déroulante : à la main dans Interface Builder, ou via l’utilisation d’une source de données. Nous allons ici nous intéresser à la seconde : l’utilisation d’une datasource.

Cet article parle de notions présentées dans ce tutoriel pour Xcode et Interface Builder. N’hésitez pas à aller vous rafraîchir la mémoire !

Dans Interface Builder, ajoutons une Combo Box dans notre vue puis, dans le premier onglet de l’inspecteur, cochons… tiens, il est marrant ce verbe conjugué au présent à la première personne du pluriel ! Hum. Cochons, donc, la case Uses Data Source.

La datasource est un objet de votre choix qui contient les données à afficher dans la liste déroulante. Cet objet retrouve et stocke les données sous la forme qu’il souhaite. Généralement, on a souvent affaire à un NSArray qui pourrait être lu depuis un fichier plist… ou depuis les User Defaults. Bref, la seule contrainte est que cet objet doit implémenter le protocole informel NSComboBoxDataSource :

- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)combo;
- (id)comboBox:(NSComboBox *)combo objectValueForItemAtIndex:(NSInteger)index

La première méthode doit retourner le nombre d’éléments qui devront être présents dans la liste déroulante. La seconde retourne l’objet pour un index donné (le message description sera envoyé à cet objet pour l’affichage dans la liste déroulante). Remarquez que ces méthodes acceptent toutes les deux une NSComboBox en argument. Ceci permet de n’utiliser qu’une seule classe pour gérer plusieurs sources de données : en fonction de l’objet combo passé en argument, il est facile de déterminer les données à utiliser.

Dans notre exemple, considérons que l’objet datasource est notre contrôleur principal, déclaré dans Interface Builder. On peut donc utiliser sa méthode awakeFromNib pour initialiser ce qu’on veut. Ici, on va récupérer des données stockées dans les User Defaults :

- (void) loadDataSource {
   // On récupère une instance des User Defaults
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   // On lit les valeurs avec la clé qu'on a choisit (ici : ComboBoxValues)
   // dataSource est un NSArray déclaré dans le fichier header de cette classe
   dataSource = [[defaults arrayForKey:@"ComboBoxValues"]
                           sortedArrayUsingSelector:@selector(compare:)];
   // Au passage, on trie les éléments par ordre alphabétique :-)
}
 
-(void)awakeFromNib {
   // On charge nos données depuis les "préférences" de l'utilisateur
   [self loadDataSource];
}

Ensuite, nous allons implémenter les deux fameuses méthodes du protocole NSComboBoxDataSource qui sont, comme vous le constatez, très complexes :

- (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox {
    return [dataSource count];
}
 
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)index {
    return [dataSource objectAtIndex:index];
}

Il nous reste à indiquer à notre NSCombBox la datasource à utiliser. Allons dans Interface Builder, sélectionnons la liste déroulante, activons l’onglet Connections de l’inspecteur puis relions l’entrée dataSource à notre contrôleur.

Très bien, mais il faut encore ajouter les données saisies dans les User Defaults, sinon l’entrée ComboBoxValues (voir la méthode loadDataSource) sera toujours un tableau vide… Et on aurait fait tout ça pour rien ! Il faut d’abord obtenir une instance de notre liste déroulante dans notre contrôleur via l’utilisation des IBOutlet (plus d’informations ici). Ensuite, il faut déterminer le moment où vous l’on souhaite que la valeur soit sauvegardée : lorsque que l’utilisateur termine la saisie dans la liste déroulante ou bien lors d’une autre action (sauvegarde des différents champs d’un formulaire, par exemple). Dans les deux cas, il faut déclarer une IBAction quelque part (plus d’informations ici). Dans cette action, il nous faut ajouter un morceau de code qui ressemble à ceci :

// Récupération de la valeur saisie dans la NSComboBox
// comboBox est un IBOutlet déclaré dans le fichier header (voir plus bas)
NSString *newValue = [comboBox stringValue];
// On vérifie si la valeur n'est pas déjà présente, auquel cas il n'y a
// rien à faire.
if ( [taskNameDataSource containsObject: newValue] == NO ) {
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   // On va ajouter un élément à notre dataSource :
   // pour cela, il nous faut un NSMutableArray (NSArray étant en lecture seule)
   NSMutableArray *mutableDS = [NSMutableArray arrayWithArray: dataSource];
   // On ajoute la nouvelle valeur
   [mutableDS addObject: newValue];
   // On stocke le tout dans les User Defaults
   [defaults setValue: mutableDS forKey: @"ComboBoxValues"];
   // Et on met à jour la liste déroulante pour qu'elle prenne la nouvelle
   // valeur en compte (il y a peut-être mieux à faire ici).
   [self loadDataSource];
}

Enfin, voici un exemple de fichier header pour notre contrôleur principal :

@interface AppController : NSObject {
	IBOutlet NSComboBox* comboBox;
	NSArray *dataSource;
}
 
// Méthodes de gestion de la datasource pour la NSComboBox
- (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox;
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)index;

Une dernière chose : il est possible de voir les préférences d’une application depuis le Terminal, grâce à la commande suivante :


defaults read identifiant.de.votre.application

L’identifiant de votre application doit être unique et on le définit dans Xcode, dans les informations de la target : dans l’arborescence de Xcode, dans la section Targets, faites un clic droit sur votre target puis Get Info et enfin onglet Properties ; le champ à renseigner est… Tah daaah : Identifier. Utilisez un nom comme les packages Java : com.entreprise.application. Attention : les defaults sont généralement synchronisés et enregistrés sur le disque à la fermeture de l’application (ou avant, mais on ne sait pas quand) : il est donc possible de ne pas les voir tout de suite à jour dans le Terminal.

CocoaDéveloppementTutoriels

Savoir si une application est lancée ou pas

6 mars 2009

Pour savoir si une application est lancée ou pas, on peut utiliser les services fournis par la classe NSWorkspace, et notamment sa méthode launchedApplications :

- (BOOL) isAppLaunched: (NSString *) appIdentifier {
   NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications];
   for (NSDictionary *appInfo in apps) {
      NSString *appId = [appInfo objectForKey: @"NSApplicationBundleIdentifier"];
      if ([appId isEqualTo: appIdentifier]) {
         return YES;
      }
   }
   return NO;
}
 
if ( [self isAppLaunched: @"com.apple.iCal"] ) {
   NSLog(@"iCal est lancé !");
}

CocoaDéveloppementTutoriels

Développer son framework Cocoa

12 février 2009

Dans cet article, je vous explique comment créer votre propre framework Cocoa (écrit en Objective-C, donc), afin de réutiliser du code dans plusieurs de vos applications. Le framework en question a pour vocation d’être inclus dans le bundle de vos applications (on ne va tout de même pas copier des librairies un peu partout !). Il y a deux grandes étapes :

  • la création du framework,
  • l’utilisation du framework dans vos applications.

Création du framework

Cocoa Framework

Dans Xcode, choisissez File > New Project… puis choisissez un projet de type Framework et plus précisément Cocoa Framework. Saisissez un joli nom pour votre framework. 

Faites un clic droit sur la target de votre framework puis choisissez Set Role > Public : ceci aura pour effet de copier les fichiers headers (.h) dans le framework, ce qui s’avère très utile pour utiliser ledit framework !

Framework Set Role Public

Éditez maintenant les propriétés de la target de votre framework (clic droit sur la target puis Get Info). Dans l’onglet Build, recherchez la section Deployment puis remplacez la valeur de la propriété Installation Directory par @executable_path/../Frameworks. Vous devriez avoir quelque chose qui ressemble à ceci :

Framework Build Properties

Ajoutez ensuite toutes les classes et ressources à votre framework puis compilez le framework (Build). Rendez-vous dans le répertoire build de votre projet et vérifiez que vous avez bien un dossier avec l’extension .framework.

Utilisation du framework dans vos applications

Il y a deux choses importantes à faire ici :

  • ajouter le framework à votre application (ce qui semble logique…),
  • faire en sorte que ce framework se retrouve dans le dossier Frameworks à l’intérieur du bundle de votre application une fois votre application compilée.

Pour ajouter le framework à votre application, faites un clic droit sur la section Frameworks dans l’arborescence du projet puis Add > Existing Frameworks… puis parcourez votre disque à la recherche de votre framework (qui est un dossier à l’extension .framework, je vous le rappelle).

application-add-existing-framework

Pour la deuxième partie, faites un clic droit sur la target de votre application puis Add > New Build Phase > New Copy Files Build Phase.

Add New Build Phase

Dans la boîte de dialogue, sélectionnez Frameworks pour le champ Destination et fermez la fenêtre (surtout qu’il fait froid en ce moment).

Destination Frameworks

Enfin, dans l’arborescence du projet, faites glisser votre framework depuis la section Frameworks vers la nouvelle section Copy Files : vous devriez alors le voir apparaître en dessous et le libellé de la phase est maintenant Copy Files (1).

Dans votre application, vous devrez inclure les fichiers headers de vos classes de cette manière :

#import "nomDuFramework/Classe1.h"

Voilà, ça devrait marcher… amusez-vous bien !

CocoaDéveloppementMacTutoriels

Glisser-déposer de fichiers dans votre application

19 janvier 2009

Dans cet article, je vais vous montrer comment on peut très simplement gérer le drag and drop de fichiers depuis le Finder vers votre application.

Il faut créer une sous-classe de NSView, par exemple DropFilesView. Dans cette classe, il faut indiquer à Cocoa que cette vue accepte la dépose de fichiers par drag and drop. Pour cela, on implémente la méthode -awakeFromNib comme ceci :

- (void) awakeFromNib {
    [self registerForDraggedTypes:
     [NSArray arrayWithObjects: NSFilenamesPboardType, nil]
    ];
    // Attention à ne pas oublier le "nil" en dernier argument de
    // arrayWithObjects !
}

Je vous rappelle que la méthode -awakeFromNib est appelée automatiquement lorsque votre application est chargée par Cocoa : c’est donc un emplacement judicieux pour initialiser des données propres à la vue. Il faut ensuite implémenter les méthodes suivantes, en fonction des besoins :

- (NSDragOperation)draggingEntered:(id )sender {
    // Appelée UNE FOIS lorsque la souris commence à survoler la vue
    // dans un processus de drag and drop.
}
 
- (NSDragOperation)draggingExited:(id )sender {
    // Appelée lorsque la souris quitte la zone de survol de la vue
    // dans un processus de drag and drop.
}
 
- (NSDragOperation)draggingUpdated:(id )sender {
    // Appelée à chaque fois que la souris est déplacée au dessus de la vue
    // dans un processus de drag and drop.
}

Ces trois méthodes retournent toutes une valeur de type NSDragOperation, indiquant si la dépose est autorisée (NSDragOperationGeneric, …) ou pas (NSDragOperationNone). Ces méthodes peuvent donc servir à vérifier que la vue accepte bien les données qui sont sur le point d’être déposées, auquel cas on retourne une valeur autre que NSDragOperationNone ; si la dépose n’est pas permise, on retourne NSDragOperationNone.

Enfin, il faut gérer le cas où l’utilisateur dépose effectivement les fichiers, auquel cas la méthode -performDragOperation: est appelée : il convient donc de la surcharger à votre guise…

- (BOOL)performDragOperation:(id)sender {
    // Appelée lorsque l'utilisateur a déposer les fichiers sur la vue :
    // on doit alors récupérer la liste des fichiers et les traiter...
    NSPasteboard *pboard = [sender draggingPasteboard];
    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
        // files contient maintenant la liste des fichiers (avec chemin complet)
        // qui ont été déposés sur la vue par l'utilisateur.
        // Faites donc ici ce que vous voulez avec files ;-)
    }
    return YES; // On indique que le drag and drop a été concluant.
}

Vous pouvez télécharger le projet complet pour Xcode : DropFilesTutorial.zip.

CocoaDéveloppementTutoriels