LASIDO is the first iOS application developed on my free time, it’s a simple music game that aims to help in improving sight reading. It’s available for both the iPhone and the iPad.
Since I’m not a graphic designer, I chose this ultra minimalistic design, the app focuses on its only feature with two modes:
training: unlimited time to understand and improve the reading
chrono: where user have to read the more notes he can in a limited 30 seconds game
Game Center is supported, so you can challenge yourself and your friends to get better at reading scores.
Les actions répétitives font parties des choses les plus agaçantes pour un développeur, et c’est pourquoi nous cherchons toujours à automatiser au maximum ces petites choses que l’on doit systématiquement faire et qui nous usent.
La création de classes et plus particulièrement de classes héritants de UIViewController dans Xcode a toujours été pour moi source de frustration, et ce pour plusieurs raisons: – je ne supporte pas le constructeur par défaut initWithNibName:bundle: qui demande à tout va le nom de fichier du XIB alors qu’une fois pourrait suffire – les templates de base n’indentent pas le code à ma façon – les pragma mark ne sont pas présentent alors qu’elles sont très pratiques – je dois toujours supprimer les commentaires d’Apple sur ce qui doit être fait ou non dans les méthodes
Voici donc la méthode pour gagner deux minutes à chaque création d’un view controller: les templates personnalisés.
Pour commencer
La meilleure façon de commencer est peu être de comprendre comment sont faits les templates déjà présents dans Xcode. Depuis Xcode 4.3, ils se trouvent sur votre Mac à cet endroit:
Vous pouvez les ouvrir, regarder comment ils sont faits, mais je vous déconseille de les modifier pour la simple et bonne raison qu’une erreur dans un de ces templates peut ne plus le faire fonctionner, voir faire crasher Xcode lorsque vous essayerez de les utiliser.
Nous allons plutôt créer nos propres templates dans le répertoire prévu à cet effet, il n’existe d’ailleurs probablement pas et c’est pourquoi nous allons le créer:
~/Library/Developer/Xcode/Templates
Une fois le dossier “Templates” créé, nous allons créer un sous-répertoire “File Templates” qui contiendra lui même un sous-dossier nommé comme bon vous semble pour vous identifier, par exemple “CC” soit:
Commençons donc par créer copier le fichier TemplateIcon.icns contenu dans n’importe quel template de base d’Xcode.
Créons ensuite les fichiers suivants:
TemplateInfo.plist:
<!--?xml version="1.0" encoding="UTF-8"?-->
AllowedTypes
public.objective-c-source
public.objective-c-plus-plus-source
DefaultCompletionName
MyClass
Description
A custom UIViewController subclass, with implementation and header files.
Kind
Xcode.IDEKit.TextSubstitutionFileTemplateKind
MainTemplateFile
___FILEBASENAME___.m
Options
Description
The name of the class to create
Identifier
productName
Name
Class
NotPersisted
Required
Type
text
Platforms
com.apple.platform.iphoneos
SortOrder
1
___FILEBASENAME___.h:
//
// ___FILENAME___
// ___PROJECTNAME___
//
// Created by ___FULLUSERNAME___ on ___DATE___.
//___COPYRIGHT___
//
#import
@interface ___FILEBASENAMEASIDENTIFIER___ : UIViewController
@end
___FILEBASENAME___.m:
//
// ___FILENAME___
// ___PROJECTNAME___
//
// Created by ___FULLUSERNAME___ on ___DATE___.
//___COPYRIGHT___
//
#import "___FILEBASENAME___.h"
@interface ___FILEBASENAMEASIDENTIFIER___ ()
@end
@implementation ___FILEBASENAMEASIDENTIFIER___
#pragma mark - Constructor
- (id)init
{
self = [super initWithNibName:@"___FILEBASENAMEASIDENTIFIER___" bundle:nil];
if (self)
{
// Custom initialization
}
return self;
}
#pragma mark - View management
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Memory
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
Cela suffit à créer nos fichiers propres et bien formatés, testez, vous verrez!
Le contenu du fichier TemplateInfo.plist
Ce fichier au format PLIST contient toute la configuration de notre template. Il est composé à partir des clés suivantes: – AllowedTypes: Un tableau déclarant le ou les types possible – DefaultCompletionName: Le nom qui sera affiché dans la fenêtre de création d’un nouveau fichier – Description: La description du template qui sera affichée dans la fenêtre de création d’un nouveau fichier – Kind: Apparement, on utilise toujours Xcode.IDEKit.TextSubstitutionFileTemplateKind, je n’ai pas plus d’informations là dessus pour le moment – MainTemplateFile: le fichier principal qui sera créé par le template – Platforms: la liste des plate-formes autorisées à utilisées le template (pour nous iOS uniquement) – SortOrder: La position du template dans la fenêtre de création d’un nouveau fichier, utile lorsqu’on a plusieurs templates pour les ordonner – Options: Contient notamment les informations sur les champs contenu dans la boite de dialogue pour créer un nouveau fichier
Le contenu des fichiers sources
Il existe là quelques macros que l’on peut utiliser afin qu’elles soient automatiquement remplacées à la création d’un nouveau fichier. Dans notre exemple, nous retrouvons les macros suivantes: – ___FILENAME___: Le nom du fichier avec extension (.h ou .m) – ___FILEBASENAMEASIDENTIFIER___: Le nom du fichier sans extension – ___PROJECTNAME___: Le nom du projet – ___FULLUSERNAME___: Le nom complet de l’utilisateur, dans mon cas “Cyril CHANDELIER” – ___ORGANIZATIONNAME___: Le nom d’organisation réglé à la création du projet – ___DATE___: La date du jour – ___TIME___: L’heure courante – ___YEAR___: L’année en 4 chiffres
Automatiser l’ajout d’un XIB
En testant tout ça, on se rend compte qu’il manque quelque chose: le XIB. Il serait intéressant d’en avoir un automatiquement créé et configuré. Pour cela, on va en créé un normalement, ajouter le nom de classe du File Owner, supprimer la status bar et mettre le layout en mode “Freeform”.
Maintenant, étudions le en l’ouvrant en mode code puis copions son code.
Au même niveau que les .h et .m, nous allons créer un fichier ___FILEBASENAME___.xib et y coller le code précedemment copié; il ne reste plus qu’à remplacer le nom de classe de test par des macros ___FILEBASENAMEASIDENTIFIER___ pour obtenir quelque chose comme ceci:
Voici donc l’arborescence finale de notre template:
Aller plus loin
Cette technique qui nous permet de gagner deux minutes et un peu de joie de vivre en codant n’est qu’un début. Sur le même principe, il est possible de créer des templates pour automatiser à l’extrème certains processus du code iOS. La création d’un projet complet et configuré est un bon exemple qui peut faire gagner énormément de temps au lancement d’un nouveau projet, l’automatisation de la création de view controllers contenant une table view et faisant l’import par exemple de cellule custom pré-configurées en est un autre. Bref, de nombreuses possibilités s’offrent à vous pour gagner du temps et ainsi confirmer le fait que les développeurs sont des êtres extrêmement feignants!
J’ai rencontré quelques problèmes lors de l’intégration de cartes Google Maps (mais ce problème peut arriver dans d’autres cas) dans une application Web utilisant Bootstrap. Le problème: les images utilisées dans la carte (marqueur, barre de scroll, etc.) étaient complement déformées sans raison apparente puisque le même code aurait très bien fonctionné ailleurs.
Après quelques recherches avec l’inspecteur d’éléments de Chrome, j’ai finalement identifié la source: un “max-width: 100%” appliqué à toutes les balises imgpar Bootstrap. En regardant un peu plus dans le le fichier bootstrap.css, voici ce qu’on peut trouver:
Essayant de découvrir Symfony 2, je cherchais un moyen de créer un nouveau type de champs de formulaire pour gérer les champs de type “Address” tout en offrant la possibilité d’utiliser une carte et l’API Google Maps pour localiser les adresses.
Je suis tombé sur un tutoriel très intéressant qui résume ça comme il faut, très bien expliqué.
En essayant d’utiliser la fonction doctrine:build –all de Symfony, un problème est survenu et m’a pris la tête aujourd’hui car PDO n’arrivait pas à trouver le socket sur lequel écrire pour communiquer avec la base de données MySQL installée en local grâce à MAMP.
L’erreur:
[...] No such file or directory (trying to connect via unix:///var/mysql/mysql.sock) in [...]
Tout simplement, le “fichier” mysql.sock n’existe pas à cet endroit. Il se trouve ailleurs, dans le répertoire d’installation de MAMP, un lien symbolique suffira à résoudre le problème…
Tout d’abord, il faut créer le répertoire /var/mysql (il n’existait pas sur mon installation), ensuite on créer le lien symbolique vers ce dossier et depuis les fichiers temporaires de MAMP. Le tour est joué!
Fix posté dans l’espoir de pouvoir aider quelqu’un, un jour, à ne pas perdre son temps.