App iOS Swift natif vs cross-platform : mon retour après 2 mondes
On me pose souvent la question. Tu fais du React Native, du Next.js, tu touches à tout. Alors pourquoi tu codes tes apps iOS en Swift natif au lieu de mutualiser ton code et de viser Android en même temps ?
Réponse honnête : parce que j'ai shippé dans les deux mondes, et qu'à un moment j'ai arrêté de me mentir. Le cross-platform, c'est génial sur le papier. Un seul codebase, deux stores, équipe réduite, time-to-market divisé par deux. Sauf que le papier ne fait pas tourner l'app sur le téléphone d'un utilisateur qui a payé pour. Et c'est là que les choses deviennent intéressantes.
Cet article, ce n'est pas un manifeste anti-React Native. J'utilise React Native sur des projets, et je le referais. C'est juste mon retour de terrain sur quand l'app iOS Swift natif gagne vraiment, et quand le cross-platform reste le bon choix. Sans religion.
Ce que le natif m'apporte que je ne retrouve pas ailleurs
Quand j'ai construit QuranWay, mon app de lecture du Coran, j'ai fait le choix du Swift natif dès le départ. SwiftUI, StoreKit, widgets, tout le package. Et plus le projet avançait, plus j'étais content de ce choix.
La performance perçue. Pas les benchmarks, la performance que l'utilisateur ressent dans son pouce. Les transitions fluides, le scroll qui ne décroche jamais, les animations cinématiques du PrayerView avec la Kaaba en 3D. En SwiftUI, je tape directement dans Metal et le système d'animation d'Apple. Pas de pont JavaScript, pas de sérialisation entre deux runtimes. L'app répond au doigt et à l'œil. Sur une app que les gens ouvrent cinq fois par jour, ça change tout.
Les intégrations système. C'est là que le natif écrase la concurrence. Sur QuranWay j'avais besoin de :
- Widgets WidgetKit pour le verset du jour et les horaires de prière sur l'écran d'accueil
- La boussole Qibla qui lit le magnétomètre en temps réel
- Les notifications locales calées sur les heures de prière calculées localement
- Les Live Activities et les complications
Tout ça existe en cross-platform via des wrappers et des modules natifs. Mais à chaque fois, tu codes du natif quand même, planqué derrière une couche d'abstraction qui te ralentit et qui casse à la prochaine mise à jour d'iOS. Autant le faire proprement directement.
StoreKit et la monétisation. Mes deux apps payantes, QuranWay et WallCraft AI, vivent de leurs abonnements. Quand j'ai migré QuranWay vers RevenueCat, quand j'ai construit un soft paywall freemium avec onze contextes de gating différents, quand j'ai géré le trial, le restore, les offres post-onboarding, j'avais besoin d'un contrôle fin sur StoreKit 2. En natif, RevenueCat et StoreKit s'intègrent comme un gant. Le paywall réagit instantanément, les achats se restaurent proprement, la gestion des entitlements est limpide. En cross-platform, c'est faisable, mais tu rajoutes une couche de friction sur la partie de ton app qui génère du cash. Je n'aime pas mettre de la friction là où il y a de l'argent.
La qualité perçue par Apple. On en parle peu, mais ça compte. Une app native respecte les Human Interface Guidelines par défaut. Les menus contextuels, le haptic feedback, le Dynamic Type, le dark mode, le support iPad, tout sonne juste parce que tu utilises les composants d'Apple. Les reviewers App Store sentent la différence. Mes apps natives passent la review plus facilement que ce que je voyais en hybride.
Là où le cross-platform reste imbattable
Maintenant, je ne vais pas te raconter que le natif gagne toujours. Ce serait malhonnête, et ce n'est pas vrai.
Le MVP qui doit sortir hier. Si je dois valider une idée sur iOS et Android en même temps, avec un budget serré et une deadline de trois semaines, je ne pars pas en Swift natif. React Native ou Flutter me donnent un produit testable sur deux plateformes pour le prix d'un. Tant que je n'ai pas de signal marché, claquer du temps sur du natif des deux côtés, c'est du gaspillage. Ship fast, valide, et tu refacto après si ça marche.
Une équipe qui vient du web. Si tu as déjà une équipe React solide, React Native te fait gagner un temps fou. Tes devs réutilisent leur cerveau, leurs patterns, parfois même des bouts de logique métier. Embaucher deux devs Swift et deux devs Kotlin quand tu as déjà quatre devs React, c'est rarement le bon calcul économique. Le meilleur outil, c'est souvent celui que ton équipe maîtrise déjà.
Les apps à dominante contenu. Une app qui est surtout des listes, des formulaires, du contenu fetché depuis une API et affiché, sans grosse exigence d'animation ou d'intégration système poussée ? Le cross-platform fait le job sans broncher. Tu ne ressentiras pas la différence de perf, et l'utilisateur non plus. Là, payer le prix du natif, c'est de la sur-ingénierie.
Le budget, tout simplement. Maintenir deux codebases natifs coûte plus cher qu'un seul codebase partagé. C'est mathématique. Si le client ne peut pas se permettre deux équipes ou un dev full-stack mobile cher, le cross-platform est la réponse responsable. Mon job de freelance, c'est aussi de dire au client ce qui est raisonnable pour son portefeuille, pas de lui vendre le truc le plus brillant techniquement.
L'histoire QuranWay Android, justement
Tiens, soyons concrets. QuranWay, je l'ai construit en Swift natif sur iOS. Et quand j'ai voulu Android, je n'ai pas migré vers du cross-platform. J'ai construit une app Android native en Kotlin et Jetpack Compose, en parité fonctionnelle avec la version iOS.
Pourquoi pas React Native pour mutualiser, du coup ? Parce que la valeur de QuranWay est précisément dans tout ce qui est dur à faire en hybride : les widgets, les calculs de prière locaux, l'audio de récitation, la boussole, les paywalls fins. J'aurais passé mon temps à écrire des modules natifs des deux côtés tout en me battant avec le pont. Autant assumer deux apps natives propres.
Et le secret, c'est que j'ai mutualisé ce qui se mutualise vraiment : les données. Le même JSON du Coran de 38 Mo, les mêmes traductions en 38 langues, le même backend analytics, le même entitlement RevenueCat. Des scripts Python font la conversion des assets et des traductions entre les deux plateformes. Le code de présentation reste natif, mais la donnée est partagée. C'est ça, pour moi, le bon découpage. Tu partages la donnée et la logique métier pure, tu spécialises l'UI et les intégrations système.
Ma règle de décision, sans langue de bois
Voilà comment je tranche aujourd'hui, sur un projet réel.
- App grand public, payante, qui tape dans les capteurs et le système, qui doit être impeccable ? Swift natif. Sans hésiter. C'est WallCraft AI, c'est QuranWay.
- MVP à valider vite sur deux plateformes, budget contraint ? Cross-platform. React Native si l'équipe est React.
- App interne ou B2B à dominante CRUD et contenu ? Cross-platform, le natif serait du gâchis.
- Produit dont le cœur est l'expérience tactile et la fluidité ? Natif, toujours. C'est là que tu gagnes la confiance de l'utilisateur.
Ma conviction, après avoir shippé dans les deux mondes : le cross-platform est un excellent outil de validation et un bon choix économique pour beaucoup de cas. Mais quand une app devient un vrai produit, qu'elle doit durer, se monétiser et impressionner, le coût du natif se rembourse vite. Le contrôle que me donne une app iOS Swift natif sur la performance, StoreKit et le système, je ne l'ai jamais retrouvé ailleurs sans tricher.
Donc non, le natif ne gagne pas toujours. Mais sur les apps qui comptent vraiment pour moi, il gagne presque tout le temps. Et je préfère assumer ce choix-là que de vendre un compromis qui se verra dans six mois sur le téléphone de l'utilisateur.
