Tutoriel pour apprendre à envoyer des push notifications via Amazon SNS en Swift 3

Ilan Benichou

Dans ce tutoriel, nous allons nous intéresser aux notifications push sur iOS à partir d'Amazon SNS en swift 3.

Prérequis :

- Avoir un compte Apple développeur ;

- Avoir un compte Amazon.

Pour information, pas de panique, la phase théorique est longue, mais nécessaire afin que vous compreniez bien la logique derrière tout ça (personnellement, je préfère voir l'ensemble et comprendre le pourquoi du comment, au lieu de reproduire bêtement sans réellement comprendre ce que je fais).

Commentez

- Titre : Tutoriel pour apprendre à envoyer des push notifications via Amazon SNS en Swift 3

- Auteur : Ilan Benichou

- Parution : 16 novembre 2017

- Licence : Copyright ® 2017 Vincent Composieux. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Qu'est-ce que les push notifications ?

- II. Apns

- III. Application

- IV. Configuration Apple

- V. Amazon SNS

- VI. Conclusion

- VII. Remerciements

I - Qu'est-ce que les push notifications ?

Bon, à part si votre téléphone est un 3310, vous avez obligatoirement eu l'occasion de recevoir une notification de la part d'une application. Aujourd'hui, cette fonctionnalité est très utilisée par la plupart des applications, donc il est « indispensable » de savoir comment ça marche et comment la mettre en place. Rassurez-vous, nous allons voir tout ça ensemble.

Il existe deux types de push notifications :

1. Locale : votre application configure les détails de notification localement et transmet ces informations au système qui gère la livraison de la notification lorsque celle-ci n'est pas au premier plan (foreground) ;

2. Remote (distante) : avec les notifications à distance, vous utilisez l'un de vos serveurs pour envoyer les données à vos utilisateurs via le service Apple Push Notification (APNs).

Pour l'utilisateur, il n'y a pas de différence entre une notification dite « locale » et une notification dite « à distance ». Les deux types de notifications ont la même apparence par défaut.

Vous pouvez personnaliser l'apparence dans certains cas, mais surtout vous choisissez comment vous souhaitez que l'utilisateur soit informé. Plus précisément, vous choisissez l'une des options suivantes pour la livraison de la notification :

- une alerte ou une bannière sur écran ;

- un badge sur l'icône de votre application ;

- un son qui accompagne une alerte, une bannière ou un badge.

Il faut toujours utiliser les notifications « locales » et « à distance » judicieusement, pour éviter d'agacer l'utilisateur. Le système permet aux utilisateurs d'activer et de désactiver la présentation des alertes, des sons et des badges par application.

Bien que les notifications puissent toujours être envoyées à votre application, le système notifie l'utilisateur uniquement pour les options actuellement activées. Je m'explique, si l'utilisateur désactive complètement les notifications, les APNs ne fournissent pas les notifications de votre application sur le périphérique de l'utilisateur, et la programmation des notifications locales échoue toujours.

II - Apns

Apple nous indique qu'il s'agit d'un service robuste, sécurisé et hautement efficace pour les développeurs, afin de propager des informations aux périphériques iOS.

Lors du lancement initial de votre application sur l'iPhone d'un utilisateur, le système établit automatiquement une connexion IP accréditée, chiffrée et persistante entre votre application et l'APNs. Cette connexion permet à votre application d'effectuer une configuration pour qu'il puisse recevoir des notifications.

L'autre partie de la connexion permet l'envoi de notifications. Le « canal » persistant et sécurisé entre un serveur provider (serveur prestataire) et les APNs nécessite une configuration dans votre compte de développeur en ligne et l'utilisation de certificats cryptographiques fournis par Apple. Un serveur provider est un serveur que vous déployez, gérez et configurez pour fonctionner avec les APNs.

1. Votre provider peut envoyer des demandes de notification aux APNs ;

2. Les APNs transmettent les payloads de notification correspondants à chaque périphérique ciblé ;

3. À la réception d'une notification, le système fournit le payload à l'application appropriée sur l'appareil et gère les interactions avec l'utilisateur.

Si une notification arrive et que l'appareil est sous tension mais que l'application ne fonctionne pas, le système peut alors toujours afficher la notification.

Toutefois, si l'appareil est éteint lorsque les APNs envoient une notification, les APNs retiennent la notification et tentent de la renvoyer plus tard.

Votre provider a les responsabilités suivantes pour échanger avec les APNs :

- Recevoir via l'APNs, des jetons de périphériques (tokens) uniques et spécifiques par dispositif ainsi que d'autres données pertinentes provenant des instances de votre application sur les devices utilisateurs ;

- Déterminer, selon la conception de votre système de notification lorsque des notifications à distance doivent être envoyées à chaque appareil ;

- Création et envoi de demandes de notification aux APNs. Chaque demande contient un payload et des informations de livraison. Les APNs fournissent ensuite les notifications correspondantes aux appareils visés en votre nom.

Bien évidemment vous pouvez avoir plusieurs providers

Vous l'aurez vite compris : c'est un sujet vaste et complexe. Rassurez-vous, il existe énormément de services qui vous facilitent la tâche concernant la partie provider.

Voici une petite liste non exhaustive des services les plus répandus :

- Firebase (gratuit) ;

- Amazon Simple Notification Service - SNS (0,50 USD par million) ;

- Urbanairship ;

- Twilio ;

Dans notre tutoriel, nous allons utiliser Amazon SNS. Amazon propose des services très utilisés par les devops afin, pour la plupart du temps, de créer l'architecture serveur de votre projet. C'est donc plus simple de centraliser tous vos services.

Avant de configurer Amazon, nous allons coder un peu l'application. C'est parti !

III - Application

Votre application doit être configurée au moment du lancement pour prendre en charge les notifications distantes. Plus précisément, vous devez configurer votre application à l'avance si elle fait l'une des opérations suivantes :

- Affiche les alertes, émet des sons ou badges d'icône en réponse à une notification d'arrivée ;

- Affiche des boutons d'action personnalisés avec une notification.

Cela signifie que vous devez configurer votre support de notification au plus tard dans l'application via la méthode didFinishLaunchingWithOptions.

Créez une « Single View Application » sous Xcode

Ensuite, il va falloir activer les notifications de votre application. Pour cela, il suffit de cliquer dans la rubrique « Capabilities » et d'activer « Push notifications », et pour finir dans « Background Modes », checker « Remote notifications ».

Rappel :

Chaque fois que votre application se lance, elle doit s'inscrire auprès des APNs. Les méthodes à utiliser sont différentes selon la plateforme, mais dans tous les cas, cela fonctionne de cette manière :

1. Votre application demande à être enregistrée auprès des APNs ;

2. Lors d'une inscription réussie, l'APNs envoie un jeton de périphérique spécifique à l'appareil ;

3. Le système connecte le périphérique à votre application en appelant une méthode dans votre délégué d'application ;

4. Votre application envoie le jeton du périphérique au fournisseur associé de l'application.

Récupérer le token auprès des APNs.

Pour initialiser l'enregistrement auprès des APNs, il suffit d'appeler la méthode registerForRemoteNotifications de l'objet UIApplication.

Appelez cette méthode au moment du lancement, dans le cadre de votre séquence de démarrage normale. La première fois que votre application appelle cette méthode, l'objet de l'application contacte les APNs et demande le jeton du périphérique spécifique à l'application en votre nom.

Le système appelle de manière asynchrone l'une des deux méthodes suivante de délégation d'application, selon le succès didRegisterForRemoteNotificationsWithDeviceToken ou l'échec didFailToRegisterForRemoteNotificationsWithError.

L'objet de l'application contacte les APNs uniquement lorsque le jeton du périphérique a changé. Si votre device token change pendant que votre application tourne, l'objet de l'application appelle la méthode didRegisterForRemoteNotificationsWithDeviceToken.

Attention : /!\ CECI NE MARCHE PAS SUR SIMULATEUR /!\ Veuillez brancher votre iPhone pour tester votre code.

1. import UserNotifications

3. // ...

5. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

6. // Override point for customization after application launch.

8. // Configure les interactions utilisateur

9. self.configureUserInteractions()

11. // Enregistrement avec les APNs

12. UIApplication.shared.registerForRemoteNotifications() // L'objet application = UIApplication.shared (singleton)

14. return true

15. }

17. func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

18. // ...

20. // Envoi le token vers votre serveur.

21. print("\n\n /**** TOKEN DATA ***/ \(deviceToken) \n\n")

23. let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

24. print("\n\n /**** TOKEN STRING ***/ \(deviceTokenString) \n\n")

25. self.forwardTokenToServer(token: deviceTokenString)

26. }

28. func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

29. print("Error: \(error.localizedDescription)")

30. }

32. func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {

33. print(userInfo)

34. }

36. // ...

38. // MARK: Send Token to server

39. extension AppDelegate {

40. func forwardTokenToServer(token: String) {

41. // ...

42. }

43. }

45. // MARK: User interactions

46. extension AppDelegate {

47. func configureUserInteractions() {

48. // iOS 10 support

49. if #available(iOS 10, *) {

50. UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }

52. return

53. }

55. // iOS 8/9 support

56. UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))

57. }

58. }

Dans la méthode didFinishLaunchingWithOptions, je fais appel à une méthode personnalisée (configureUserInteractions) afin de demander l'autorisation à l'utilisateur de recevoir des notifications de l'application. On remarquera que dans cette méthode, j'ai ajouté une condition en fonction de la version de l'OS de l'iPhone.

Depuis iOS10, un nouveau framework appelé UserNotifications a été introduit et doit être importé au début afin d'avoir accès à la classe UNUserNotificationCenter.

Je me suis permis également d'ajouter un petit bout de code (dans didRegisterForRemoteNotificationsWithDeviceToken) afin d'imprimer le token (jeton) reçu par l'APNs.

Lorsque votre application reçoit une push notification c'est par la méthode didReceiveRemoteNotification. Cependant cette méthode existe sous la forme fetchCompletionHandler, qui permet de gérer l'arrière-plan.

C'est à vous de développer la logique réelle qui s'exécute lorsqu'une notification génère une interaction. Par exemple, si vous avez une application messenger, une notification push « nouveau message » doit ouvrir la page de discussion pertinente et faire apparaître la liste des messages à partir du serveur. Utilisez userInfo qui contiendra toute donnée que vous envoyez à partir de votre back-end d'application, tel que l'ID de chat, dans l'exemple de messagerie.

IV - Configuration Apple

Comme mentionné plus haut, nous devons générer un certificat SSL pour le client de notification push qui permet à votre fournisseur de notification de se connecter aux APNs.

N.B. : Chaque App ID est requis pour avoir son propre certificat SSL client.

Le certificat SSL client généré est un certificat universel qui permet à votre application de se connecter aux environnements de développement et de production.

Pour générer un certificat SSL de client universel, il faut :

1. Accéder à Certificates ;

2. Cliquer sur le button (+) à droite ;

3. Sélectionner dans la partie développement « Apple Push Notification service SSL (Sandbox) » et cliquer sur « Continue ». Bien évidemment, si vous devez mettre en production vous devez sélectionner la partie « production » ;

4. Choisir L'App ID qui correspond à votre paquet ID et cliquer sur « Continue » ;

5. Apple vous demande de créer un « Certificate Signing Request » (CSR). Pour générer manuellement un certificat, vous avez besoin d'un fichier de demande de signature de certificat (CSR) à partir de votre Mac. Pour créer un fichier CSR, suivez les instructions ci-dessous :

1. ouvrez l'application « Keychain Access »,

2. cliquez sur Trousseaux > Assistant de certification > Demandez un certificat à une autre autorité de certificat (cf. capture d'écran) ;

3. Dans la fenêtre Informations sur le certificat, entrez les informations suivantes :

1. Votre adresse de messagerie,

2. Dans le champ Nom commun, créez un nom pour votre clé privée (par exemple, Pepito Dev Key),

3. Le champ Adresse de l'adresse CA doit être laissé vide,

4. Pour « La requête est », sélectionnez « Enregistrée sur le disque »,

5. Cliquez sur continuer ;

6. Uploader votre fichier .certSigningRequest précédemment créé ;

7. Votre certificat est prêt, téléchargez-le.

Encore un effort, c'est presque fini !

Maintenant, nous devons transformer notre fichier aps_development.cer en fichier .p12 pour Amazon SNS, afin que celui-ci le convertisse en .pem. Pour ce faire, c'est très simple :

1. Double-cliquez sur votre fichier précédemment créé. Ça l'ajoutera dans votre application Keychain ;

2. Faites un clic droit sur celui-ci et cliquez sur Exporter ;

3. Choisissez bien le format .p12, puis l'application Keychain vous demandera un mot de passe.

Bien évidemment vous pouvez utiliser OpenSSL en CLI afin d'exporter votre .cer en .pem :

$ openssl x509 -in aps_development.cer -inform DER -out myapnsappcert.pem

Pour vérifier que tout est en ordre, il suffit d'aller sur la liste des App IDs, de cliquer sur l'ID de votre App, puis sur « Edit ». Dans la partie Push notification, vous devriez voir que vous avez bien un certificat dans la partie Development.

Enfin fini ! Je vous l'accorde cette partie est fastidieuse et lourde. Il ne manque plus que la partie Amazon SNS.

V - Amazon SNS

Amazon SNS est un service web qui coordonne et gère la diffusion ou l'envoi de messages à des clients ou à des endpoints (points d'accès) abonnés. Il existe deux types de clients :

1. Les éditeurs (publishers), également appelés producteurs (producers) ;

2. Les abonnés (subscribers), également appelés consommateurs (consumers).

Les publishers communiquent de façon asynchrone avec les subscribers en produisant et en envoyant un message à une rubrique (topic), qui est un point d'accès logique et un canal de communication.

Les subscribers (par exemple, des serveurs web, des adresses e-mail, des files d'attente Amazon SQS, des fonctions AWS Lambda) consomment ou reçoivent le message ou la notification via l'un des protocoles pris en charge (Amazon SQS, HTTP/S, e-mail, SMS, Lambda) lorsqu'ils sont abonnés au topic.

Lorsque vous utilisez Amazon SNS, vous créez une rubrique (topic) et définissez des stratégies d'accès à cette dernière de manière à déterminer quels publishers et subscribers peuvent communiquer avec le topic.

Les publishers envoient des messages aux topics qu'ils ont créés ou à ceux sur lesquels ils sont autorisés à publier. Plutôt que d'inclure l'adresse d'une destination spécifique dans chaque message, les publishers envoient un message au topic. Amazon SNS établit une correspondance entre le topic et la liste des abonnés à ce topic, puis remet le message à chacun d'eux.

Chaque topic possède un nom unique qui identifie le point de terminaison d'Amazon SNS, de manière à ce que les publishers puissent publier des messages et que les subscribers puissent s'inscrire pour recevoir des notifications.

Les subscribers reçoivent tous les messages publiés dans les topics auxquels ils sont abonnés, et tous les subscribers à un topic reçoivent les mêmes messages.

Étape 1 : Création d'un topic

1. Connectez-vous à la console AWS , cliquez sur « Create topic » ;

2. Renseignez un nom.

Étape 2 : Inscription de votre application mobile auprès d'Amazon SNS

1. Cliquez sur « Create platform application » ;

2. Indiquez un nom à votre application ;

3. Dans la zone « Push notification platform », sélectionnez la plateforme auprès de laquelle l'application est inscrite. Dans notre cas nous choisissons « Apple development » ;

4. Dans la zone « Push certificate type », sélectionnez « iOS push certificate » ;

5. Choisissez le fichier .p12 à créer ultérieurement ;

6. Entrez votre mot de passe et cliquez sur « load credentials ».

Étape 3 : Ajoutez votre token à votre application

Avant de vous abonner à un topic, il faut ajouter votre token généré à votre application.

Connectez votre iPhone, mettez en place votre projet et vous verrez votre token dans la console.

Pour ajouter votre token :

1. Ouvrez la console AWS ;

2. Allez dans la rubrique Application, et sélectionnez votre application précédemment créée ;

3. Cliquez sur « Create platform endpoint » et ajoutez votre token.

Une fois votre token enregistré, veuillez copier l'Endpoint ARN qui vous servira pour la partie suivante.

Étape 4 : Abonnement à un topic

Pour recevoir les messages publiés dans un topic, vous devez abonner un endpoint à ce topic. Un endpoint est une application mobile, un serveur web, une adresse e-mail ou une file d'attente Amazon SQS... qui peut recevoir des messages de notification d'Amazon SNS. Une fois que vous avez abonné un endpoint au topic et que l'abonnement est confirmé, le endpoint reçoit tous les messages publiés dans ce topic.

1. Ouvrez la console AWS ;

2. Cliquez sur la rubrique topic et sélectionnez votre topic ;

3. Cliquez sur « Create subscription », sélectionnez comme protocol application et collez votre Endpoint ARN.

Étape 5 : Publier un message

Rien de plus simple, il vous suffit de sélectionner votre topic et de cliquer sur publish.

Amazon met à votre disposition un json generator si vous ne savez pas comment écrire le payload.

Résultat :

VI - Conclusion

La mise en place de push notifications n'est pas un sujet hyper complexe, mais nécessite néanmoins un peu de connaissances. Une fois que vous avez compris le système de certificat (.pem/.p12) qui permet d'identifier chaque application, le reste est plutôt simple (pour l'exemple que j'ai utilisé).

VII - Remerciements

Nous remercions Eleven labs pour nous avoir autorisé à publier ce tutoriel.

Nous remercions également Winjerome pour la mise au gabarit et maxy35 pour la relecture orthographique.