Category Archives: Développement

Désactiver les NSLog en release

Le NSLog est l’outil de base dans le développement et le déboguage d’application Cocoa (donc Cocoa Touch). Seulement, l’utilisation de NSLog n’est pas si anodine qu’elle peut paraître … Le fait d’envoyer une chaine de caractère à la sortie console consomme des ressources.

Certes, c’est peu de choses, mais quand un NSLog est inclus dans une boucle, se déclenche à chaque touchesMoved: (par exemple), il commence à ralentir très sérieusement le fonctionnement de l’application. Sans compter qu’une fois l’application distribuée, il est possible pour l’utilisateur final de lire ce qui se trouve dans les logs … Ce qui n’est pas forcement voulu pour le développeur.

L’idée serait donc, quand on est en configuration de compilation « release », de désactiver (automatiquement les NSLog). Continue reading

Iphonelite3: Une nouvelle librairie SQLite pour iPhone

Je viens de découvrir aujourd’hui une nouvelle librairie permettant de simplifier l’utilisation de SQLite3 sur iPhone: Iphonelite3. L’idée global du projet est de ne pas avoir à coder une seule ligne de SQL dans son application. Il s’agit tout bêtement de faire de la persistance d’objet. Là où le concept est intéressant, c’est qu’il ne se base pas sur des objets héritant d’une quelconque implémentation de serialisation.

Non, l’idée est plus axée « hibernate » (que l’on trouve avec Java). Vous passez votre objet au gestionnaire de base de données et il s’occupe de tout le reste. Je ne vais pas continuer à faire l’article de Iphonelite3, son auteur le fait très bien sur son blog dédié. Notez que le projet est, pour le moment, en phase alpha et ne doit donc pas être utilisé en phase de production. Mais c’est à regarder avec attention.

Au passage, je rappellerais ce qui se fait sur ce segment en ce moment. Il y a les projets FMDB (que j’utilise dans deux de mes projets), SQLitePersistentObjects (que je n’ai pas pu utiliser dans mon dernier projet car il gère mal les NSMutableDictionary) et EntropyDB.

Une UITableView triée par ordre alphabétique

L’UITableView est un outil idéal pour afficher une certaine quantité de données à l’utilisateur. Seulement voilà, quand cette quantité de données devient grande, il peut être intéressant de permettre à l’utilisateur d’accéder rapidement à l’information qu’il souhaite.

Une des solutions est d’utiliser le tri par ordre alphabétique. C’est l’idéal pour l’affichage de contacts (par exemple). On peut même aller plus loin. Pourquoi simplement se limiter à un tri par ordre alphabétique ? Pourquoi ne pas proposer une catégorisation des entrées en prenant en compte la première lettre de la propriété qui nous intéresse. C’est ce que nous allons voir dans ce billet. Au final, nous arriverons à ce résultat:

alphabeticaltableviewfinalscreen
Continue reading

Créer une UITableViewCell personnalisée à partir d’Interface Builder: exemple complet

Il y a peu, j’exposais ma solution pour Créer une UITableViewCell personnalisée à partir d’Interface Builder. Suite au commentaire de Bruno Da Silva, je vous laisse une version complètement fonctionnelle de l’implémentation de cette méthode.

Il s’agit d’une TableView qui va chercher les dernières photos Flickr avec pour tag « xmas ». Pourquoi donner un exemple aussi compliqué ? Tout simplement parce que je n’ai vraiment pas le temps de faire un exemple complet en ce moment et je voulais publier un exemple rapidement. J’ai donc récupéré rapidement un exemple de code que j’ai fais en interne pour le boulot.

La partie de code qui va chercher les images sur FlickR n’est pas de moi. L’auteur n’ayant pas laissé d’informations le concernant dans le code, je ne pourrais plus vous dire qui c’est (et ça me désole vraiment).

Voici l’archive contenant le projet Xcode complet (toute l’intelligence concernant la méthode pour l’UITableViewCell se trouve dans MyTableViewController.m à la méthode - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath): télécharger MyTableViewDemo.zip.

Réduire la hauteur d’une UITableView

Prenons un cas simple: on a une UIView qui contient une simple UITableView (avec le UITableViewController qui va bien) ainsi qu’une UIToolBar en bas. On se retrouve avec un léger problème: la UITableView ne se redimensionne pas automatiquement en hauteur. Ainsi, les derniers éléments se retrouvent « cachés » par la barre. Voici un exemple fait à la va-vite avec Interface Builder (la UIToolBar a été volontairement mise en transparence pour illustrer le problème):

uitableviewsizeproblem

Le souci, c’est qu’il n’est pas possible de préciser dans le code la taille d’une UITableView. Après avoir essayé plusieurs solutions (dont certaines était plutôt farfelue), j’en ai retenu une. C’est celle qui m’a semblé la plus propre, simple et efficace.
Continue reading

Créer une UITableViewCell personnalisée à partir d’Interface Builder

Le problème

La TableView est un composant essentiel de l’HIM de l’iPhone très simple à développer pour des besoins simples. Clairement, si on doit afficher à l’utilisateur des cellules avec une seule ligne de texte, ça se fait les doigts dans le nez.

Là où les choses se corsent, c’est quand il faut créer des cellules personnalisées. Avec, par exemple, deux UILabel et une UIImageView. En effet, il n’existe pas de méthode pour charger un nib (comme l’habituel initWithNibName:). Ainsi, on se retrouve forcé à créer tout nos éléments et à les placer à la main dans le code. C’est loin d’être quelque chose d’agréable, simple et rapide à faire. Sans compter qu’au moindre changement de design de la cellule, on perd un temps fou.

La solution

Non, l’idéal c’est de pouvoir utiliser Interface Builder pour construire ses cellules… Après quelques essais, recherches et erreurs, voici la solution que j’ai trouvé (et que j’utilise):

Continue reading

Afficher l’image d’un contact de l’AddressBook de l’iPhone

Il y a peu, je parlais de la sérialisation d’un contact dans l’AddressBook de l’iPhone. Toujours dans la même veine, voyons comment afficher, dans une application, la photographie d’un contact de l’AddressBook.

L’idée est de partir du ABRecordRef correspondant au contact dont on souhaite afficher l’image. A partir de là, on vérifie que ce contact dispose bien d’une photo dans sa fiche (via ABPersonHasImageData(). Pour finir, on récupère les données brutes de l’image ( ABPersonCopyImageData()) et on crée la UIImage qui va bien (via initWithData:).

Au final, voilà ce que ça donne:

Après, il ne faut pas oublier de libérer myAvatarData puisqu’il est devenu inutile. Charge à vous ensuite d’afficher avatarImage dans le UIImageView qui va bien. Simple non ?

Serialiser l’identifiant d’un contact dans l’AddressBook de l’iPhone

Dans la série des billets concernant le développement sur iPhone, en voici un nouveau qui reste dans la veine du précédent (« Récupérer une adresse email dans le AddressBook de l’iPhone »).

L’idée ce coup là, c’est de récupérer un identifiant d’un contact. Je m’explique: dans l’application que je développe je dois enregistrer (sur un serveur distant) des informations concernant un contact sélectionné par l’utilisateur. Clairement, il s’agit du nom, du prénom et de l’adresse email. Puis, dans un second temps, ces données peuvent revenir sur l’iPhone.

Seulement, il pourrait être intéressant de faire directement le lien, lors du retour de l’information, entre les personnes désignée par les données sur le serveur et l’entité qui la représente dans le AddressBook. Pourquoi ? Pour plusieurs raisons. Tout d’abord, imaginez que l’on modifie les informations concernant la personne (cas typique: on a fait une faute de frappe quand on a saisi son nom la première fois ou elle change d’adresse mail). Et bien si on est capable de détecter ce changement quand les données reviennent sur l’iPhone, on pourra répercuter les modifications sur le serveur. La seconde raison est qu’il peut être sympa de faire un lien vers la fiche de la personne dans le AddressBook quand on affiche son nom dans l’application.

Quand on arrive dans le peoplePickerNavigationController: shouldContinueAfterSelectingPerson (donc que l’utilisateur a sélectionne un contact), on ne dispose que d’un objet de type ABRecordRef. Ce type d’objet est difficilement « sérialisable » … Comprenez par là qu’il serait difficile de le transformer en une chaine de caractère et de refaire l’opération inverse (pour le « dé-sérialiser »).

La solution est d’utiliser ABRecordGetRecordID() qui retourne un identifiant unique du contact dans l’ AddressBook. Cette fonction renvoie un objet de type ABRecordID (qui n’est ni plus ni moins qu’un entier !). Au final, pour la convertir en chaine de caractère ça donne (mPerson étant notre objet de type ABRecordRef):

Ensuite, l’opération inverse (récupérer le ABRecordRef a partir du de la chaine de caractère), c’est simple:

Notez que dans le cas où le contact n’existe pas (plus), ABAddressBookGetPersonWithRecordID() renvoie NULLVoilà, maintenant on peut effectuer n’importe quelle opération comme si on venait de récupérer le contact à partir du peoplePickerNavigationController.

Récupérer une adresse email dans le ContactBook de l’iPhone

J’avais dit que je parlerais ici même des petites astuces ou gros problèmes rencontrés lors du développement de mon application iPhone. L’objectif est assez clair : faire gagner quelques précieuses heures aux prochains qui rencontreront les mêmes problèmes que moi. Le premier cas concret concerne le carnet d’adresse de l’iPhone.

L’idée est d’aller récupérer les informations concernant un contact que l’utilisateur aura désigné dans son carnet d’adresse. Je ne vais pas expliquer ici comment mettre en place l’interface de sélection d’un contact (le peoplePickerNavigationController). En effet, Mickaël Morvan le fait très bien dans son article sur développez : « iPhone SDK: Accès au carnet d’adresses de l’iPhone ».

Comme vous avez pu le voir, récupérer le nom et le prénom d’un contact sous forme de chaine de caractère est assez simple. Par contre, si on applique la même technique à l’adresse email (en utilisant kABPersonEmailProperty à la place de kABPersonLastNameProperty), on lève une exception Terminating_Due_To_Uncaught_Exception

Pourquoi donc ? La première chose à comprendre c’est qu’un contact n’a qu’un seul nom. Mais il peut avoir plusieurs adresses email… Par conséquent, un ABRecordCopyValue(mPerson, kABPersonEmailProperty) ne renverra pas une seule valeur mais une collection de valeurs ! Alors, évidement, quand on veut mettre ça dans un NSString ça ne passe pas.

Pour faire simple, on va considérer que seule la première adresse email nous intéresse (généralement c’est la principale). Ce qui revient à vouloir prendre la valeur à l’index 0 de la collection de valeurs. Ensuite, et bien on caste en string. Concrètement, voilà ce que ça donne :

Après, il n’est pas dur de compléter en permettant de choisir une adresse email particulière (voir dans la littérature Apple du coté de ABMultiValue).

Mine de rien, le problème a l’air tout simple, mais il a fallu quelques heures pour en arriver là. Sans compter que toutes les recherches faites sont tombées sur des gens posant la question et n’ayant pas de réponse !

PHP >= 5.1 et la gestion avancée des dates

La gestion des dates est toujours problématique sur Internet. En effet, nous ne sommes pas tous dans les mêmes fuseaux horaires. Nous n’utilisons pas tous les mêmes normes d’affichage (un exemple simple: les anglophones mettent le mois avant le jour … nous: non). Il y a aussi la gestion des heures d’été, la façon d’exprimer le nom d’un fuseau horaire, …

Bref, c’est une joyeuse pagaille ! Sans compter que cette gestion (au niveau système) n’est pas la même en fonction du système d’exploitation qui héberge l’application PHP en question. Voilà pourquoi PHP intègre (depuis 5.1 en expérimental et 5.2 en natif) deux nouveaux objets: DateTimezone et DateTime permettant de gérer les dates proprement et indépendamment de l’OS.

A ce sujet, Julien Pauli vient de publier un tutorial sur Developpez présentant l’utilisation de ces nouveaux objets. Il n’y a rien à redire: ça simplifie grandement la gestion fiable et précise du temps ! Voici un exemple de code:

Bref, un article à lire absolument !

Lire “PHP5 : La gestion avancée des dates” sur Developpez