Swift et l’accessibilité : introduction à VoiceOver

Photo by Daniel Ali on Unsplash

Et si on parlait d’accessibilité pour nos applications mobiles ? En 2017, rien qu’en France, 12 millions de personnes seraient touchées par un handicap (source). Alors vous imaginez dans le monde !

J’ai été contactée pour mon application KayakTraker par une personne atteinte de déficience visuelle, qui voulait savoir si l’application était compatible VoiceOver… gros blanc 😦 Du coup, me suis prise au jeu… 🙂

Et bonne nouvelle, sous iOS, il existe beaucoup de fonctions d’accessibilité, dont VoiceOver dont nous allons parler ici. Comme en plus, c’est relativement simple à mettre en oeuvre, alors pourquoi s’en priver ?

Pourtant, encore trop souvent, l’accessibilité pour les concepteurs.rices d’applications mobiles passe loin après le design, les fonctionnalités, les patterns… Et c’est dommage car avec un peu d’empathie et d’efforts, il est possible de faire beaucoup mieux !

En fait, si vous utilisez Xcode, votre application est même probablement déjà compatible en grande partie avec VoiceOver. Apple à fait pour nous une grande partie du travail, et nous donne des outils sympas pour le terminer 🙂

Donc commençons par une petite application de démo : 1 Label, 2 Buttons, 1 TextField. Lorsque l’on clique sur le bouton « Click me ! », on affiche « Hello » dans le TextField, et le bouton « Raz » remet le TextField à 0 :

Pour tester l’application avec VoiceOver, on peut dans un premier temps l’installer sur un device physique. Il faudra ensuite activer Voice Over dans les paramètres : Général > Accessibilité > VoiceOver. Cela permet déjà un premier test et de voir quelles informations manquent.

Mais ce n’est pas très pratique pour développer…

Heureusement, si il n’est pas possible (actuellement) d’activer les options d’accessibilité sur le simulateur, il est possible d’utiliser l’Accessibility Inspector depuis Xcode. Pour cela, rendez-vous dans le menu Xcode > Open Developer Tool > Accessibility Inspector.

On voit bien que le plus gros est fait, mais il reste quelques finitions…

Pour cela Apple à prévu les options d’accessibilité depuis le storyboard. D’une façon générale, chaque élément (Button, TextField…) possède des options d’accessibilité, qu’il suffit d’activer et de compléter :

Pour plus d’infos sur les traits, vous pouvez vous référer à la documentation officielle : https://developer.apple.com/

Voilà, une fois ces étapes accomplies, nous avons une application nettement plus accessible pour les personnes qui en ont besoin ! Ce n’est vraiment pas beaucoup de travail comparé à l’immense service que nous rendons !

Et le plus beau pour la fin : les options d’accessibilités gèrent aussi les traductions, comme toutes les autres éléments de l’interface 🙂

Vous pouvez donc retrouver vos labels et gérer vos traductions dans les fichiers strings dédiés. D’ailleurs, pour le rafraîchissement de ces fichiers, BartyCrouch est votre ami… mais cela fera l’objet d’un autre article.

Voilà pour cette introduction à l’accessibilité pour les applications iOS / Swift via VoiceOver. ce n’est bien sûr qu’une introduction, et VoiceOver ne prend en compte qu’une partie de l’accessibilité.

L’accessibilité se pense en globalité : au niveau du design, au niveau du parcours… J’en parlerai également dans de futurs articles ! En attendant, comme d’habitude, n’hésitez pas à me faire part de vos remarques / suggestions dans les commentaires !

L’enregistrement NSUserDefaults en Swift

L'enregistrement clé-valeur en swift _ nsuserdefaults

L’enregistrement de données sous forme de clé-valeur en développement mobile à déjà été abordé dans l’article sur les SharedPreferences.

Aujourd’hui, je vous propose de faire la même chose, mais en Swift. C’est beaucoup plus simple, mais nous nous limitons alors aux plateformes Apple (iOS, iPadOS, MacOS, WatchOS).

Comme pour les SharedPreferences, NSUsersDefaults est donc un système simple et rapide qui permet d’enregistrer des valeurs de type Float, Bool, Double, Int, mais aussi des objets (array, dictionary…. ), et des urls. C’est donc une façon de gérer la persistance des données à la fois simple et puissante 🙂 .

Pour cette démo, j’ai créé une petite application très simple dans laquelle l’utilisateur enregistre une phrase, et celle-ci est stockée comme une clé-valeur grâce à UserDefaults :

Afin de vérifier la persistance, n’hésitez pas à relancer l’application, et vous verrez que votre phrase reste mémorisée 🙂

Alors pour utiliser UserDefaults, il faut déjà créer une instance de UserDefaults, et définir ses clés de préférences :

Ensuite, l’enregistrement d’une valeur se fait avec l’instruction « préférences.set » :

Et la lecture d’une valeur avec :

Et c’est tout !

Ce qui fait que notre controller contient juste ce code :

Je pense que c’est la méthode la plus simple en Swift pour sauvegarder des informations ! Mais elle est aussi très puissante, puisqu’il est non seulement possible d’enregistrer des valeurs « simples », comme des entiers, des nombres et de booléens, mais aussi des valeurs plus complexes, comme des tableaux et des dictionnaires. En « bidouillant » un peu, on peut même enregistrer des images !

Bref, pas de raisons de s’en priver !

Comme toujours, le code source est disponible sur mon dépôt Git : https://gitlab.com/vinceBar/swift-nsuserdefaults-ios-demo-project

Et si vous avez des questions / suggestions, n’hésitez pas, commentez !

Développement Swift / iOS : Améliorer la qualité de son code grâce à SwiftLint

La qualité du code est actuellement LE sujet dans le monde du dev (et avec raison !). Si vous êtes développeur.se pro et passionné.e, vous n’êtes sans doute pas passé à coté !

Donc, si le TDD est votre religion, que vos tests unitaires sont nickels et couvrent 100% du code, qu’Xcode ne retourne plus un seul warning, et que Sonarqube est devenu votre meilleur ami… Et bien vous pouvez encore vous améliorer, grâce à SwiftLint !

Si Sonarqube fera l’objet d’un autre article de blog, je vais aujourd’hui vous parler de SwiftLint.

SwiftLint, c’est un outil créée et maintenu par Realm pour améliorer le respect des conventions d’écritures en Swift, disponible ici : https://github.com/realm/SwiftLint

Comme souvent, il y a plusieurs manières de l’intégrer dans un projet, personnellement, j’aime bien Cocoapods !

Comme code d’exemple, je vais reprendre la démo « InfoKayak », mise à jour pour Swift 5.

Sans SwiftLint, Xcode 11.3 ne trouve rien à redire au code (pas de warning, pas d’erreur) :

Editez maintenant le fichier Podfile en y ajoutant la ligne :  » pod ‘SwiftLint’  » :

Mettez à jour et installer les pods, puis rouvrez le projet avec Xcode. Pour le moment, il n’y a pas de changements 🙂

En fait, pour activer SwiftLint, il faut un petit script. Dans les « Build Phases » du projet, cliquez sur le « + » , ajoutez une « New run script phase », et mettez-y ce script :

On Build et Oh ! 286 warnings et 22 erreurs 😦 WTF ?

Allez, avant de faire un burn out, une bonne nouvelle, SwiftLint est capable de corriger automatiquement une grosse partie de ces problèmes 🙂 .

Pour cela, depuis un terminal, mettez vous dans le dossier de votre projet, et exécutez la commande « ./Pods/SwiftLint/swiftlint autocorrect« .

Ensuite, effacez le dossier de build d’Xcode, et au besoin, relancez l’IDE. Normalement, la situation devrait s’être grandement améliorée : il n’y a plus que 2 erreurs et 5 warnings à corriger manuellement, chose que je fais immédiatement… 😉

Dans certaines situations, on ne peux pas corriger (cas de librairie externes lesquelles nous n’avons pas la main…), il est donc possible de paramétrer SwiftLint plus finement.

Pour tout ce qui est règles globales, il faut créer un fichier .swiftlint à la racine de votre projet. Par exemple, le mien contient ceci :

Lorsqu’il s’agit d’un besoin temporaire, on peut désactiver une règle directement dans le code avec l’instruction // swiftlint:disable <rule> . La liste des règles se trouve ici : https://realm.github.io/SwiftLint/rule-directory.html

Voilà, j’espère que cette petite introduction vous aura donné envie de vous mettre à Swiftlint et à vous mettre à la qualité ! En tous cas moi, je suis accro !

Swift Map Filter Reduce mémo

Lorsque l’on pense opérations sur des types Array ou Dictionary en Swift, on a souvent le réflexe for-in loop… Mais Swift propose d’autres méthodes comme map, filter, reduce… potentiellement plus efficaces. Voici donc un petit mémo à ce sujet 🙂

Map

Map sert à parcourir une collection er à appliquer la même opération à chaque élément de cette collection. La fonction map retourne un array contenant le résultat. Dans l’exemple suivant, la fonction map est utilisée pour retourner le carré de chaque item d’un tableau :

Le type de retour de la fonction map n’est pas limité au type des éléments d’origine :

Et enfin, la fonction map peut être utilisée sur tout type de collection :

Filter

La fonction filter parcourt un array ou une collection et retourne un array contenant les éléments correspondant à la condition demandée. Ex: recherche des entiers divisibles par 2:

Reduce

Reduce sert à combiner tous les éléments d’une collection pour créer une nouvelle valeur. Dis comme cela, ce n’est pas très parlant, mais voici quelques exemples :

  • Ajouter toutes les valeurs d’un array à une valeur initiale de 15 :
  • Fusionner des chaînes :

flatMap et compactMap

  • flatMap :
  • compactMap :

En résumé :

  • map permet de retourner un array contenant le résultat d’une transformation appliquée à chaque item.
  • filter retourne un array contenant seulement les éléments correspondant à une condition donnée.
  • reduce retourne une seule valeur calculée en combinant chaque item avec une valeur initiale.

Un dev iOS au pays de Mac OS

Cela faisait un petit moment que je n’avais pas publié d’articles. Je vous rassure, je n’étais pas perdue au milieu du désert de Gorafe, mais plutôt en plein projet… macOS.

J’ai en effet eu le bonheur de contribuer à un projet mac OS écrit en Swift, et cela m’a donné l’occasion de me frotter un peu plus sérieusement à Cocoa et consorts… et d’en faire un petit retour d’expérience 🙂 .

Venant tout droit du dev iOS, donc d’UIKit, de prime abord, cela ressemble énormément. On remplace tout ce qui est UI par NS (ex : UITextField devient NSTextField) et ça repart… pas très loin justement 😦

En effet, on s’aperçoit vite que toute la syntaxe est un poil différente. Par exemple, pour changer le texte dans un champ texte, sous UIKit, on utilise la syntaxe : monJoliTextFielt.text = « Bonjour » Et sous Cocoa, la syntaxe est monJoliTextField.stringValue = « Bonjour »

Ces petites différences, ajoutées à un certain manque de documentation en ligne (en tous cas pour Swift) comparé à iOS font que le développement peut parfois devenir un peu… lent 😦 Il faut parfois (souvent) adapter la syntaxe ObjectiveC à Swift, et ça prend du temps… Vive StackOverflow !

Mais franchement, une fois assimilé, la programmation d’une application Mac OS en Swift devient franchement plaisant.

En tant que dev iOS et donc utilisateur Xcode, je retrouve la construction d’interfaces par storyboards. Là encore, les éléments ne sont pas exactement les mêmes, mais avec un peu de patience et de recherches, on s’y retrouve. Et pour le reste, cela reste du Swift.

Du coup, si j’étais au départ un peu anxieux par rapport au fait de passer de mon iOS « chéri » à Mac OS, je me suis rapidement pris au jeu et je serais maintenant partant pour recommencer sur un autre projet Mac OS 🙂

Et puis, il ne faut pas oublier qu’encore une fois, Apple pense à nous faciliter la vie avec le projet Marzipan, depuis renommé Catalyst :). Donc si tout va bien, d’ici quelques temps, on ne se prendra plus la tête à développer une application pour iOS ou Mac OS, mais on développera une application tout cours !

Bon pour le moment, je vous laisse, j’ai des applis à mettre à jour pour iOS et iPad OS 13 🙂

Programmation Swift : iOS Developer Notes For Professionals

ios Dev Pros

Voici mon nouveau livre de chevet : iOS Developer Notes for Professionals !

Je crois que tout le langage Swift est abordé dans ce livre ! Cela va de la création toute simple d’une UIView au parsing de JSON, tout en passant par l’usage de des frameworks les plus utilisés (Fastlane…) et des designs paterns (MVC, MVVM…).

Bref, le top du top pour le développeur Swift !

Bon, finalement, le lire avant de s’endormir n’est pas forcément la meilleure idée, mais c’est le genre de livre à garder impérativement sous la main toute la journée de développement !

En plus, il est gratuit !

A télécharger (sans modération) ici :

iosDeveloperBook

Git Memorandum

Comme pour tous.tes les développeur.ses, Git fait partie de mon quotidien… Et comme tous.tes les développeur.ses, il m’arrive aussi de galérer avec Git 😦 .

C’est pourquoi j’ai décidé de créer ce billet de blog « Aide mémoire », destiné aussi bien aux débutant.es qu’au utilisateur.ices averti.es… Article sur lequel je partagerai bien entendu mes petites galères et mes (grandes) solutions !

Lire la suite

Tutoriel Swift : envoyer des sms / iMessages

des sms en swift

Suite à la demande d’un client, j’ai pas mal bossé en janvier sur les envois de sms via une application, que cela soit en utilisant les api’s natives (comme ici), ou en utilisant des sms proxys comme Twilio.

C’est donc l’occasion de faire un petit récapitulatif de ce que j’ai découvert et de faire un petit tutoriel sur l’envoi de sms en Swift sur iOS.

Mais d’abord, voici ce que j’ai « découvert » sur la gestion des sms / iMessages par iOS12

D’abord, la différence fondamentale entre un sms et un message type iMessage / mms / rcs… est que le sms ne nécessite pas de réseau « data » pour fonctionner, alors que les 3 autres types de messages nécessitent une connexion avec des données mobiles (3G, 4G…).

De plus, iOS semble « savoir » si votre correspondant.e possède un téléphone iOS, donc la possibilité de recevoir des iMessages, ou si votre le téléphone de votre correspondant.e est sur un autre OS, et donc utilise le format sms. Je précise que cela fonctionne que votre correspondant.e soit enregistré.e dans vos contacts ou non.

It’s a mirical !!!

Et bien non. Il fallait y penser, mais en fait avant d’envoyer votre message, le système vérifie si le numéro de téléphone de votre destinataire se trouve dans la bas de donnée iCloud d’Apple. Et oui. Par contre, en tant que développeur.se, n’espérez pas accéder à cette fonctionnalité… j’ai testé pour vous.

Autre comportement inattendu d’iOS 12, le rendu d’un sms est différent si le numéro de téléphone émetteur est enregistré dans vos contact ou non. Par exemple, si vous envoyez un lien, dans le premier cas, votre destinataire aura un petit carré gris affichant « Touchez pour voir le contenu », et dans le second cas, seule l’url sera visible.

Enfin, iOS, contrairement à Android, impose une confirmation manuelle avant l’envoi d’un message (en fait, on comme vous le verrez, on se contente de faire passer un numéro de téléphone et un message à l’api d’iMessage).

Voila pour la théorie, et maintenant, la pratique !

L’application d’exemple est très simple : un champ texte pour mettre le numéro de téléphone de votre destinataire, une zone de texte pour mettre votre message et un bouton « Envoyer « , et 2 ou 3 décorations 🙂

Sous iOS, pour envoyer un sms / iMessage, nous aurons besoin du framework « MessageUI« . C’est lui qui s’occupe de tout, via MFMessageComposeViewController.

Donc, tout se joue dans les 2 fonctions « sendMessage » et « messageComposeViewController » :

« sendMessage » récupère le contenu des champs « phoneNumber » et « message« . Puis, après avoir controlé que les capacités du device (il n’y à rien à rajouter dans Info.plist), envoie les données à « messageComposeViewController« . On récupère ensuite le résultat.

Comme d’habitude, le code complet de l’application présentée sur trouve sur Gitlab : https://gitlab.com/vinceBar/ios-sms-demo

Et si vous avez des questions, remarques… commentez !

La liste des APIs publiques

Il y a quelques temps, j’avais rédigé un article concernant la parfaite toolkit API pour développeur.se mobile. Cet article est bien sûr régulièrement mis à jour et vous le trouverez ici : https://vincent-barousse.blog/

Cette fois, je vous propose rien de moins que l’annuaire des APIs publiques !

A retrouver sur ce site : https://public-apis.xyz