Blog tech

Envoyer des notifications iOS en ruby

Rédigé par Martin Catty | 24 juillet 2012

Le besoin

Par défaut Mail sur iPhone est incapable de relever automatiquement les emails dans les sous dossiers, pour les comptes de type imap.

Comme j’utilise des tris serveur avec Dovecot c’est particulièrement fastidieux de vérifier chaque sous dossier à la main en situation de mobilité.

Je me suis donc dit qu’il serait pratique d’avoir une notification pour ces emails.

Pré-requis

Tant qu’à faire je souhaitais résoudre ce problème en ruby. Heureusement pour nous Grocer est là.

Pour envoyer des notifications il va nous falloir deux choses importantes:

  • Un compte developer Apple, afin d’obtenir un certificat permettant de délivrer des notifications.
  • Le token du device sur lequel envoyer les notifications.

Ce dernier est différent de l’UDID de l’appareil. Pour le récupérer nous allons devoir créer une mini application iOS et l’installer sur l’appareil. C’est expliqué sur le dépôt de Grocer.

Il s’agit uniquement de demander à l’utilisateur l’autorisation pour envoyer des notifications et d’afficher le token dans le log.

  // AppDelegate.m
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSLog(@"Registering for remote notifications");
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

    return YES;
  }

  - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"deviceToken: %@", deviceToken);
  }

  - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Error in registration. Error: %@", error);
  }

Une fois l’application buildée et installée, il suffit de la lancer et de consulter les logs du terminal depuis la section organizer de Xcode.

Le fameux token devrait s’y retrouver.

Le nez dans le code

Le code d’envoi des notifications se trouve sur Github.

Paramétrage

Pour commencer il faut paramétrer l’application dans config/global.yml

On peut y mettre plusieurs boîtes. Par défaut j’utilise le format qu’on retrouve pour les DNS, à savoir foo@example.bar devient foo.example.bar

Une fois au moins un compte imap configuré, il reste à coller le certificat d’envoi de notifications dans le dossier certs avec le nom certificate.pem.

On peut décider de ne pas notifier l’arrivée de mail dans certaines boîtes avec skip.

Comment ça marche?

Pour éviter plusieurs notifications concernant les même emails (même s’ils n’ont pas été lus), nous allons stocker les identifiants des emails.

Pour cela nous utilisons une base de données SQLite avec une unique table où nous allons stocker le nom de la boite (sous la forme foo.example.bar.folder.subfolder) et les identifiants des messages non lus.

Le parcours des différents sous dossiers des différentes boites se fait avec net/imap.

Lorsque la différence entre ids des messages non lus (ex: 3,4,5) et ids stockés en base (ex: 1,2,3) renvoie des valeurs (4, 5) nous envoyons une notification.

À noter donc que la notification se fait par sous dossier. On peut donc potentiellement recevoir plusieurs emails à la suite.

Voilà pour une introduction à la mise en place de Grocer, qui remplit parfaitement son rôle. Pour un tour d’horizon complet des différentes options je vous invite à aller jeter un œil sur le Github.

Autrement, vos commentaires sont les bienvenus!

L’équipe Synbioz.

Libres d’être ensemble.