Notre équipe de développement mobile utilise SwiftUI depuis 2022 pour développer l’application Infomaniak Mail sur iOS. À ce jour, c’est l’un des plus gros projets open source écrits 100% en SwiftUI. L’attractivité du nouveau framework d’Apple ne fait pas de doute mais reste un défi pour les développeurs. Très peu d’entreprises ont l’audace de l’utiliser à 100%. D’un côté, il y a la jeunesse du framework avec une documentation floue ou incomplète. De l’autre, il faut changer en profondeur les logiques apprises. Dans cet article, les développeurs d’Infomaniak partagent leur retour d’expérience sur l’adoption de SwiftUI pour Infomaniak Mail.

Pourquoi choisir SwiftUI pour lancer notre app Mail dédiée ?

Nous voulions favoriser les évolutions rapides de l’application et pouvoir accéder aux dernières nouveautés. SwiftUI est la base des prochaines innovations sur toutes les plateformes d’Apple : non seulement sur iOS, mais aussi sur macOS et VisionOS.

Ce nouveau framework amène plusieurs avantages pour les développeurs :

  • Sa syntaxe déclarative permet de décrire les interfaces utilisateurs de manière plus concise et lisible.
  • Son système de preview permet de visualiser immédiatement les changements sans nécessiter de compilation.
  • Le découpage des vues en composants réutilisables optimise la maintenabilité de l’application.
  • L’intégration avec Swift permet d’utiliser les derniers ajouts du langage comme l’API FormatStyle directement dans les zones de texte.
  • Le support de l’internationalisation et de l’accessibilité facilite l’utilisation de l’app par tous sans avoir à écrire de code explicite, contrairement à UIKit.

Si on fait le bilan, la manière historique de faire avec UIKit cohabite encore très bien avec SwiftUI, mais pour combien de temps ? Comme on le voit à travers de nombreux exemples, Apple met en avant son nouveau framework de façon déterminée. Les nouveautés des OS nécessitent SwiftUI pour être implémentées, comme c’est le cas pour les widgets ou les Live Activities. Le nouveau framework devient donc un incontournable pour supporter les dernières fonctionnalités. Nous voulions également éviter que l’application se repose sur une technologie trop rapidement dépassée.

Les challenges de SwiftUI par rapport à UIKit

Si aujourd’hui notre équipe est formée à SwiftUI, elle est passée par des erreurs, des tâtonnements et des retards, principalement pour ces raisons :

1. Continuer d’assurer le support des anciens appareils

Pour limiter l’obsolescence programmée et les remplacements trop fréquents des appareils, il faut pouvoir les conserver le plus longtemps possible. Nous restons volontairement avec SwiftUI 3 sorti avec iOS 15 plutôt que SwiftUI 5 publié avec iOS 17 afin de supporter les appareils de tous nos clients fonctionnant avec iOS 15 (environ 5 % de nos utilisateurs).

Cette volonté représente cependant un défi pour l’équipe mobile d’Infomaniak : le framework, publié en 2019 avec iOS 13, est encore jeune et évolue très rapidement. Bien qu’Apple comble rapidement les manques de SwiftUI au fil des années, supporter iOS 15 limite l’utilisation des nouvelles APIs.

2. La gestion du changement

Le virage vers SwiftUI a été initié en 2022, alors que le développement d’un POC avait déjà débuté avec UIKit. Nous n’avions alors aucune expérience de ce nouveau framework avec nos applications préexistantes. Certains de nos développeurs qui expérimentaient déjà de leur côté par une veille technologique active ont pris l’initiative sur les bonnes pratiques en entraînant les autres avec eux.

Même si l’environnement était familier, nous avons dû dépasser une certaine résistance au changement et apprendre une nouvelle manière de faire.

Nous avons pris la décision de tout développer en utilisant SwiftUI. Chaque nouvelle vue ou composant utilisait SwiftUI et les vues développées précédemment avec UIKit ont été remplacées au fur et à mesure quand les maquettes changeaient et nécessitaient du développement.
Philippe Weidmann, Tech Lead iOS – Infomaniak

La gestion du changement était le premier grand défi pour une équipe formée et habituée à UIKit, car la logique de développement est fondamentalement différente avec SwiftUI :

Avec la méthode historique UIKit (la méthode impérative), on gère manuellement la disposition et le comportement de chaque élément de l’interface par des contraintes très détaillées. Il faut définir comment les vues et les contrôles doivent être positionnés et dimensionnés relativement les uns aux autres et par rapport à leurs conteneurs. Il faut également mettre en place la logique permettant de réagir aux différents évènements comme la saisie d’un champ et la mise à jour des éléments en conséquence.

Avec la nouvelle approche SwiftUI, il suffit de décrire la vue que l’on veut obtenir avec les états et les relations entre les éléments (la méthode déclarative). Le framework gère automatiquement la mise en page et les interactions en fonction des changements de données de l’application (programmation réactive).

Au final, SwiftUI est plus efficace et intuitif dès lors qu’on est parvenu à s’approprier la logique.

L’apprentissage passe par plusieurs phases avec une tendance à conserver nos réflexes comme :

  • Écrire du SwiftUI à la manière UIKit (nous pensions bien faire).
  • Privilégier l’écriture en UIKit pour résoudre rapidement un problème plutôt que de l’aborder avec SwiftUI, nécessitant souvent l’apprentissage via des tutoriels.

Puis la courbe d’apprentissage se redresse. Avec UIKit, on a la mainmise sur chaque détail. Cela donne une compréhension totale de ce qu’il se passe. En contraste, cette facilité apportée par SwiftUI cache les mécanismes internes. Cela peut rendre certains bugs visuels ou des problèmes de performances insaisissables sans une connaissance approfondie de l’intérieur du framework.

Pour dépasser cela, notre équipe s’est appuyée sur la communauté, sur de la recherche et de très nombreux tests. L’empirisme nous a permis d’évaluer les directions à prendre et de dépasser les blocages.

3. La fluidité et les performances

SwiftUI est un framework simple et rapide à prendre en main, mais plus compliqué pour créer des interfaces efficaces et optimisées. Les optimisations ne sont pas nécessairement bien documentées par Apple.

Dans notre cas, l’application Infomaniak Mail doit se comporter de la même manière pour les utilisateurs qui ont 12 mails dans leur boîte de réception que pour ceux qui en ont 50 000. Idem pour les avatars des contacts qui doivent s’afficher de façon fluide dans toutes les discussions, peu importe le nombre de participants. Ce n’était pas le cas.

Comme nous l’expliquons plus bas, nous nous sommes rendu compte qu’il y a des choses qu’on ne doit pas faire avec ce Framework. Encore faut-il que l’information existe.

4. Personnalisation de l’application : les contraintes UI/UX

Infomaniak mise sur sa propre identité visuelle cohérente sur toutes les plateformes, Android et iOS, quitte à s’éloigner des conventions d’Apple.

SwiftUI est parfois résistant à la personnalisation des composants et offre peu d’options. Apple pousse en quelque sorte les développeurs à utiliser le design system d’Apple, c’est-à-dire le look and feel qu’on retrouve dans les applications natives comme Mail ou Rappels.

Nous avons dû à plusieurs reprises créer nos propres composants plutôt qu’utiliser ceux mis à disposition, voire parfois lutter contre le framework pour parvenir à nos fins. Par exemple, en utilisant les mécanismes natifs, les applications affichent le titre des vue (ici le nom du dossier Réception pour l’app Mail) de manière centrée. L’application Infomaniak Mail doit utiliser sa mécanique propre pour afficher le titre à sa manière :

Affichage du titre pour Infomaniak Mail
Affichage du titre dans une application native (ici Mail)

Pour rendre la rédactions des e-mails plus accessible, notre app dispose d’un bouton « Nouveau message » appelé bouton flottant. Il n’existe pas dans le design system iOS, mais plutôt dans les applications Android. Nous avons dû le développer à partir de zéro.

Ce bouton doit également se rétracter automatiquement pour laisser de la place à l’utilisateur afin de consulter sa liste des mails lorsqu’il la fait défiler. C’est un défi technique, car il est nécessaire de savoir quand l’utilisateur fait défiler la liste et SwiftUI ne propose pas de mécanisme simple pour le faire.

Bouton flottant déployé
Bouton flottant rétracté

L’app Infomaniak Mail permet aussi à l’utilisateur de sélectionner des mails par un long appui pour agir sur plusieurs messages. Cette mécanique n’est pas proposée nativement par SwiftUI, car elle s’éloigne des standards d’Apple. Nous avons donc tout créé par nous-mêmes.

La personnalisation nous a demandé d’apprendre à dépasser les scénarios prévus par Apple.

SwiftUI simplifie la création des composants et l’itération sur le design, mais la personnalisation reste difficile. Pour les composants, UIKit demande plus de temps et est plus verbeux, mais il est beaucoup plus simple de faire ce qu’on veut pour la personnalisation.
Philippe Weidmann, Tech Lead iOS – Infomaniak

L’implémentation des grands composants de l’application Infomaniak Mail avec SwiftUI

Trois grands composants de l’app Mail ont posé des défis spécifiquement liés à SwiftUI :

1. La liste des e-mails : la partie qui demande le plus de performances

La liste des e-mails est un point central de l’expérience utilisateur. Elle peut contenir une quantité importante d’éléments, dans plusieurs modes d’affichage (compact, standard, large). Dans la pratique, certains utilisateurs gardent tous leurs e-mails dans un seul dossier. Nous devons donc nous assurer que la navigation soit toujours fluide et performante, quel que soit le nombre d’e-mails contenu dans la liste de l’utilisateur.

Dans sa documentation, Apple laisse penser que l’utilisation du composant “List” de SwiftUI devrait être simple : on prend chaque élément de notre liste puis on l’affiche. Théoriquement, le développeur ne devrait pas se poser plus de questions.

Mais la réalité est plus complexe. Lorsqu’il y a beaucoup d’éléments, les contraintes d’un smartphone peuvent impacter les performances. Des mécanismes intégrés à iOS existent depuis toujours pour afficher des listes longues sans impacter la fluidité. On parle de réutilisation des cellules d’une liste lorsque le système affiche uniquement les éléments visibles à l’écran et va réutiliser les éléments au fur et à mesure qu’ils apparaissent et disparaissent de l’écran. SwiftUI cache ces mécanismes aux développeurs et le framework assure lui-même la réutilisation des cellules pour des raisons de simplicité.

La manière dont nous avions initialement implémenté notre liste ne permettait pas à SwiftUI d’assurer correctement la réutilisation des éléments et de calculer les différences lors d’un changement dans celle-ci. Concrètement, une liste de 50 000 e-mails pouvait prendre plus d’une seconde à s’afficher sur les plus vieux appareils tout en ralentissant considérablement le reste de l’interface. La documentation du composant List ne donnait aucune explication à ce problème.

Les problèmes de performance sont un sujet récurrent avec SwiftUI. La documentation pour développeurs ne faisait pas explicitement mention de l’impact sur les performances de l’utilisation d’un contrôleur de Flow directement à l’intérieur d’une liste. C’est seulement grâce aux conseils d’un court passage d’une vidéo (Demystify SwiftUI Performance) pour la WWDC 2023 que nous avons pu résoudre nos problèmes et améliorer significativement nos performances.

La documentation d’Apple est en général de bonne qualité, mais nous recommandons vivement aux développeurs de suivre les sessions vidéos des WWDC qui regorgent d’informations intéressantes et sont très bien produites. Le tout disponible gratuitement.

2. La rédaction d’un message

La partie rédaction des messages est composée de ces deux principaux éléments :

  • La partie en-tête (qui comporte les destinataires et l’objet du mail)
  • La partie corps du message (qui est une webview)

Dans l’en-tête, l’app Mail propose la suggestion de contacts avec le nom et l’avatar qui s’affichent. Lorsque le contact est sélectionné et validé, son nom se transforme en un composant appelé « chip » (petit bouton) et s’ajoute à la liste des destinataires. S’il est activé par l’utilisateur, ce chip affiche une boîte de dialogue permettant de supprimer le destinataire. Ces éléments ne sont typiquement pas prévus par SwiftUI et ont nécessité un développement sur mesure.

Dans la partie corps du message, l’utilisateur rédige son texte dans une WebView. Autrement dit, il écrit une page HTML sans s’en rendre compte. Côté développeurs, on doit établir le lien entre le contenu du message tel qu’il s’affiche dans la Webview et ce qui va finalement être envoyé au destinataire (le code natif) par le serveur.

La rédaction d’un nouveau message est un des points d’entrée principaux d’une application e-mail. C’est donc un point de friction potentiellement important dans l’expérience utilisateur. La webview sur mobile étant un composant assez lourd, notre équipe va développer un nouveau conteneur de zéro durant cette année pour aller chercher de meilleures performances.
Philippe Weidmann, Tech Lead iOS – Infomaniak

3. Le menu latéral personnalisé

Tout comme le bouton flottant « Nouveau message », le menu latéral glissant qu’on peut déployer en appuyant sur le bouton « hamburger » en haut à gauche n’est pas un composant habituel sur les plateformes Apple. C’est plutôt un élément du « Material Design » de Google (Android). Il repose sur une librairie qui permet d’optimiser et d’uniformiser le comportement des éléments sur tous les appareils. Mais suivant comment on conçoit ce menu glissant avec SwiftUI, cela peut être très peu performant. Nous avons dû le développer entièrement de zéro pour arriver au même look and feel.

Ces personnalisations demandent un développement spécifique en soi, mais génèrent aussi plus de travail sur la durée.

Comme nous avons fait pas mal de composants non prévus par SwiftUI, nous devons systématiquement reporter ces ajouts pour les autres plateformes comme iPadOS et éventuellement pour macOS. Des adaptations que nous n’aurions pas dû faire si nous avions suivi le framework d’Apple à la lettre sans intégrer notre propre design system. L’arrivée de nouvelles plateformes comme VisionOS par exemple pousse à la réflexion, car cela complexifie l’adaptation de nos personnalisations.

Le comportement naturel d’un menu latéral est de s’ouvrir ou de se masquer depuis le côté gauche de l’écran en suivant le pouce de l’utilisateur. Étant donné qu’il n’existe pas de composant natif en SwiftUI pour ce comportement, il a fallu implémenter cette vue de zéro. Concrètement, cela implique de superposer la vue du menu à la vue principale et de la décaler sur la gauche jusqu’à ce qu’elle devienne invisible pour la masquer et inversement pour l’afficher.

Au départ, le contenu du menu n’était pas séparé du conteneur du menu en lui-même, ce qui posait de gros problèmes de performance. En effet, pour chaque variation du décalage du menu (donc chaque pixel d’animation vers la gauche ou la droite), la vue entière était redessinée. Sur un téléphone récent, le ralentissement n’était pas visible, mais consommait tout de même trop de CPU d’après nos critères. Sur un téléphone plus ancien, l’utilisateur pouvait percevoir un ralentissement.

La première étape a donc été d’identifier et de mesurer le problème à l’aide d’instruments pour être sûr que les modifications réalisées apportaient un vrai gain.

Ensuite, nous avons séparé la vue qui contient le menu (le conteneur) du contenu en lui-même. Cela permet au framework SwiftUI de ne redessiner que le conteneur sans toucher au contenu et ainsi de gagner énormément de performances.

Bilan du passage de UIKit à SwiftUI

Si c’était à refaire ? Nous choisirions toujours SwiftUI, mais nous avancerions plus progressivement.

Avec le recul, c’était assez audacieux et même douloureux de passer de 100 % à SwiftUI en une fois.

J‘étais au départ plutôt contre le fait de développer l’app Infomaniak Mail entièrement en SwiftUI. Ça a été une décision difficile à prendre, mais aujourd’hui, si c’était à refaire, nous le referions. Ça nous octroie un sacré avantage sur la maintenance et l’évolution de l’application dans le futur.
Joris Bodin, Developer Team Leader – Mobile et Desktop

On constate les avantages de SwiftUI en retournant travailler sur nos applications plus anciennes écrites en UIKit. Un ViewController UIKit qui gère une liste peut rapidement se retrouver avec plusieurs centaines de lignes à écrire et à maintenir, alors que quelques lignes SwiftUI pourraient suffire.

En développant en SwiftUI, on se concentre essentiellement sur la donnée à afficher, tandis que UIKit demande beaucoup d’enrobage pour arriver à ce que l’on veut.

SwiftUI représente l’avenir. Le framework amène des avancées qui changent la vie, comme la prévisualisation du rendu de l’application en direct dans l’interface de développement. Historiquement, Apple a montré que lorsqu’elle propose une technologie de pointe comme SwiftUI, elle la maintient dans le temps. Donc nous savons que nos efforts ne seront probablement pas balayés dans trois ans, contrairement à Google qui propose plus de nouveautés, mais qui les laisse de côté plus rapidement. Sur cet aspect, l’équivalent SwiftUI sur Android, JetPack Compose, est poussé par une autre entreprise que Google, JetBrains. Nous pensons que cela offre à JetPack Compose plus de chances de perdurer.

Même si UIKit est loin d’être dépassé et reste une bonne option dans de nombreux cas, SwiftUI s’impose petit à petit par lui-même. Ses nombreux atouts facilitent le développement et en fait le futur des plateformes Apple. Bien que sauter le pas puisse faire peur, il ne faut pas hésiter à se lancer.
Valentin Perignon, développeur iOS Infomaniak

Un des principaux défis qui s’est imposé à nous était : « Comment avoir une identité propre tout en respectant les guidelines d’Apple ? » Nous avons vu que ce qui n’est pas prévu par le framework entraîne un plus grand volume de travail.

Nous aimerions conseiller aux développeurs qui hésitent à se lancer de le faire petit à petit. Un enseignement tiré de cette expérience est que « si vous trouvez que c’est compliqué, c’est probablement que vous faites quelque chose de faux ».

La documentation SwiftUI ne couvre pas tout et nous avons dû enquêter pour trouver des réponses, notamment au sujet des performances. Nous conseillons de regarder les vidéos des conférences en ligne (WWDC) d’Apple qui contiennent des informations clés qui peuvent débloquer une situation.

Pour nos autres applications, kDrive est développé à l’origine sur iOS 12 avec UIKit parce que SwiftUI est arrivé seulement à partir d’iOS 13 avec des composants manquants. Comme nous n’avons pas pu utiliser SwiftUI à l’époque, nous n’avons pas la possibilité de réutiliser des composants de kDrive dans l’app Infomaniak Mail. Nous comptons justement migrer sur SwiftUI petit à petit, par morceaux, ayant appris de notre expérience avec l’app Mail.

Professionnellement, maîtriser une technologie de pointe comme SwiftUI représente une valeur importante sur le marché du travail. Nous conseillons tout de même aux jeunes développeurs de connaître UIKit, car beaucoup d’entreprises n’ont pas encore fait ce changement. SwiftUI est une jeune technologie « à la mode » que peu de monde maîtrise actuellement et nous sommes heureux que cela soit à présent notre cas.

En savoir plus