La distribution d’applications iOS

le 15/02/2024 par Jordan Chapuy
Tags: Software Engineering, Mobile

Certificate, Provisioning Profile, Ad-Hoc, Distribution, Code signing, … Bienvenue dans le monde complexe de la distribution d’applications iOS. C’est un sujet qui peut dérouter, et malheureusement, on s’y confronte dès lors que l’on veut distribuer une application.

Peu importe le framework utilisé (“je fais du natif iOS”, “je fais du cross-plateforme Flutter, React Native”), et quelque soit le type de poste (“j’archive avec mon macbook”, “c’est le runner de ma CI qui archive”), on n’y échappe pas.

Cette mécanique imposée par Apple n’a pas son équivalent côté Android ou sur le web. Pas étonnant que ça provoque quelques maux de têtes au premier contact. Ça arrive même à des développeurs iOS plus expérimentés. Mais comme tout, ça s’apprend.

Une fois que l’on a compris les rouages, on est beaucoup plus à l’aise pour résoudre les problèmes qui gravitent autour de la distribution d'applications iOS. Et c’est là que j’interviens aujourd’hui. Je vais vulgariser certains concepts de base pour, je l’espère, permettre de mieux comprendre les problèmes qui surviennent et trouver plus facilement des solutions.

Je démarre en douceur, en grattant un peu la surface, ce qui est visible par tous. On plongera en profondeur et avec un peu plus de technique ensuite. Ça va bien se passer.

Les canaux de distribution

Regardons tout d’abord les différentes possibilités à notre disposition pour utiliser une application iOS que l’on développe soi-même, et les spécificités de chacune d’elles.

  • Simulateur

Depuis mon poste, je peux installer l’application en cours de développement sur un simulateur et l’utiliser comme bon me semble. C’est ce qu’un développeur fait en continu. C’est rapide, on peut debugger.

  • Appareil

Depuis mon poste, je peux installer l’application en cours de développement sur un appareil relié à ma machine (câble ou WiFi). C’est ce qu’un développeur va faire également pour tester l’application sur un vrai appareil. On peut également debugger. L’application expire au bout d’un temps.

  • Store de bêta alternatif

Je peux distribuer une version bêta de mon application sur des stores comme Firebase Distribution, Appaloosa, App Center. C’est ce que l’on utilise souvent pour déployer en continu les incréments réalisés, pour que l’équipe interne puisse installer les différentes versions de l’application sur leurs téléphones. Il faut enregistrer l’UUID de chaque appareil (maximum 100) et inviter l’utilisateur sur ce store alternatif. L’application expire au bout d’un temps.

  • TestFlight (interne)

Je peux distribuer une version bêta de mon application sur TestFlight en mode “tests internes”. C’est une alternative intéressante aux stores bêta alternatifs car avec TestFlight, on ne s’embête pas à enregistrer des appareils. Il faut seulement inviter les utilisateurs sur TestFlight, avec un maximum de 100 personnes. L’application expire au bout de 90 jours.

  • TestFlight (externe)

Je peux distribuer une version bêta de mon application sur TestFlight en mode “tests externes”. C’est LA solution pour faire des tests à grandes échelles avec des utilisateurs externes. Il suffit de les inviter ou de leur donner un lien pour qu’ils rejoignent le test. On peut monter jusqu’à 10.000 personnes. Apple effectue une revue de l’app à chaque nouvelle version. Petit avantage intéressant, on peut passer une version directement en prod (App Store) si on est satisfait.

  • App Store

Je peux distribuer l’application finale sur l’App Store. Tous les utilisateurs y auront accès, sans contrainte, limite ou enregistrement à effectuer. C’est la prod ! C’est par l’App Store que les utilisateurs classiques découvrent et installent toutes leurs applications.

  • Store de prod interne

Je peux distribuer l’application finale sur un store interne à mon entreprise. C’est l’option que l’on va choisir si on veut déployer une application réservée à ses salariés - elle doit rester privée, on veut contrôler qui peut l’installer. Un exemple : les vendeurs d’une grande enseigne qui auraient une application spéciale sur leurs iPads pour gérer les stocks du magasin et la caisse. On ne veut pas la voir sur l’App Store. L’application expire au bout d’un temps.

  • Store de prod alternatif

Je peux distribuer l’application finale sur un store alternatif. Apple va permettre la création d’autres stores pour installer des applications de production. Je ne m’étalerais pas plus sur ce sujet ici, c’est encore trop récent, je n’ai pas toutes les informations. La mécanique devrait être assez similaire, avec quelques éléments supplémentaires.

J’ajoute une précision. Quand je dis “l’application expire au bout d’un temps”, c’est à cause des Provisionning Profiles ou d’une limite spécifique au canal de distribution. On peut obtenir une application qui “n’expire jamais” si on pousse des nouvelles versions avant les dates limites.

Les types de distribution selon Apple

Descendons d’un cran en profondeur, je vais commencer à utiliser des termes techniques d’Apple. On a vu qu’il y avait beaucoup de possibilités pour installer une application iOS, mais Apple les regroupe selon 4 types de distribution. Ces termes seront utiles pour créer les bons Provisionning Profiles.

  • Development. On installe l’application directement sur un appareil, et celui-ci doit être relié à un Mac.
  • Ad-Hoc. On archive l’application (on crée un binaire) afin de le distribuer sur des stores de bêta alternatifs (Firebase, Appaloosa, App Center, …).
  • App Store Connect. On archive l’application afin de la distribuer sur les stores officiels d’Apple (App Store et Test Flight).
  • In-House. On archive l’application afin de la distribuer sur un store de production interne.

J’en profite pour également introduire la notion de Certificate. On va se pencher sur les deux types qui sont intéressants dans notre cas.

  • Development. C’est utile lorsque l’on veut signer l’application pour l’installer directement sur un appareil.
  • Distribution. C’est utile dès lors que l’on veut signer l’application pour la distribuer, peu importe comment (Ad-Hoc, App Store, In-House) et où (store de bêta, App Store, TestFlight, store interne, …).

À noter qu’il existe ces mêmes types pré-fixés par “iOS” ou “Mac”. C’est la même chose, sauf qu’ils contraignent à leurs plateformes.

Les ingrédients

Maintenant, entrons dans le vif du sujet, allons dans la profondeur. La page ressources du compte développeur regroupe tous les éléments nécessaires pour distribuer une application. On y retrouve ceux qui sont existants, expirés, et on peut en créer de nouveaux.

Tous ces éléments sont créés sur notre compte développeur, ce qui a deux conséquences. Ils peuvent servir à toutes les applications sous la propriété de ce compte - cool. Les limites de création concernent l’ensemble du compte, ce n’est pas par application - pas cool.

  • Devices

C’est la liste des appareils enregistrés sur notre compte développeur. Il est nécessaire d’ajouter ici l’UUID d’un appareil sur lequel on souhaite installer l’application en direct ou distribuer sur un store de bêta (donc des distributions de type Development et Ad-Hoc).

La limite est de 100 appareils (pour tout le compte !). Je n’ai qu’une seule occasion par an de supprimer des appareils : le mois précédant la date anniversaire de la souscription au Apple Developer Program. Apple nous le rappelle quand on approche de cette période.

  • Identifiers

Chaque application possède un identifiant unique sous la forme com.example.app qu’il faut enregistrer dans cette section. On y associe également des Capabilities - des autorisations d’utiliser certains services (Push Notifications, HomeKit, Siri, …).

Pour une même application, on peut être amené à créer plusieurs Identifiers. Par exemple pour différencier des environnements (com.example.app et com.example.app.staging). L’intérêt sera de pouvoir installer les deux applications sur un même téléphone.

  • Certificates

Dès que l’on veut installer une application sur un appareil ou la distribuer, il faut signer l’archive (le binaire) de l’application. C’est là qu’entre en jeu le certificat. Il indique que cette application provient de notre compte.

En général, chaque développeur crée son certificat de type Development, afin de pouvoir installer l’application en cours de développement sur son appareil. Et il faut au moins générer un certificat de type Distribution pour déployer l’application sur des stores.

Un certificat est lié au compte développeur, et non à une application - un seul certificat de Distribution peut donc signer toutes nos applications. D’ailleurs, on est limité à un maximum de 3 certificats de type Distribution. Il sera intéressant d’en générer un second lorsque l’on s’approche de la date d’expiration du premier. Ou parce que l’on veut le donner à une équipe externe et pouvoir le révoquer facilement sans nous impacter.

Attention, on ne peut télécharger le certificat contenant la clé privée de signature qu'au moment de sa création. La machine qui signe les applications doit avoir le certificat avec la clé privée dans son keychain.

Un certificat expire au bout d'un an. Une application ne se lancera pas si le certificat associé est expiré ou invalide. Il faudra distribuer une nouvelle version avec tous les éléments valides. L’App Store n’est pas concerné par ce problème.

  • Provisioning Profiles

Un profil est la glu qui lie tous les éléments. On associe un Identifier, un Certificate, un type de distribution et on sélectionne des devices. Le profil permettra d’indiquer à l’appareil si l’application peut être installée et à quels services elle a accès.

On en crée autant qu’il y a d’applications, de type de distribution (Development, Ad-Hoc, …) et d’environnement (si on a plusieurs Identifiers). On se retrouve rapidement à en avoir une grande quantité.

Un profil expire au bout d’un an, et devient invalide si le certificat auquel il est associé expire. La machine qui compile l’application doit avoir les bons profils installés.

Une application ne se lancera pas si le profil qui a été installé avec devient expiré ou invalide. Il faudra archiver et distribuer une nouvelle version avec tous les éléments valides. L’App Store n’est pas concerné par ce problème.

  • API Keys

Bonus. La clé d’API permet de s’identifier auprès d’Apple pour utiliser des services de l’App Store Connect. Ce sera utile pour les runners d’une CI lorsqu’une commande interagit avec le compte développeur (ex: récupérer un profile) ou avec l’App Store (ex: soumettre une application).

La génération des clés d’API se fait sur l'App Store Connect, onglet Users and Access, et non depuis le compte développeur.

La mayonnaise

On a tous les ingrédients nécessaires pour faire monter une belle mayonnaise, il n’y a plus qu’à les assembler. Je vais illustrer avec plusieurs scénarios qui peuvent arriver tout le long d’une année.

  • On commence une nouvelle application

On enregistre un Identifier pour notre application et on ajoute les différents appareils de l’équipe dans Devices. Chaque développeur génère son Certificate (Development) puis on crée un Provisioning Profile (Development) (associant les appareils de l’équipe et les certificats des développeurs).

Pour pouvoir déployer les incréments sur un store de bêta, on génère un Certificate (Distribution) puis un Provisioning Profile (Ad-Hoc) en cochant bien tous les appareils de l’équipe.

Pour pouvoir déployer sur TestFlight et sur l’App Store, je vais créer un Provisioning Profile (App Store). On a déjà le bon certificat.

  • Un certificat expiré

On génère un nouveau Certificate du même type puis modifie tous les Provisioning Profiles qui étaient associés à l’ancien certificat pour sélectionner le nouveau.

  • Un profil a expiré ou est invalide

On modifie le Provisioning Profile pour le recréer. Pas besoin de le supprimer, on peut cliquer sur “Edit” et le sauvegarder à nouveau.

  • Il faut ajouter un nouvel appareil

On ajoute l’appareil dans la liste des Devices puis on modifie les Provisioning Profiles pour cocher l’appareil nouvellement ajouté. Attention, cet appareil ne pourra installer que les prochains builds de l’application (qui seront archivées et signés avec ce nouveau profil).

  • On veut distinguer un nouvel environnement

On suit quasiment les mêmes étapes que la création d’un nouveau projet avec le nouvel Identifier que l’on va créer. Il n’y a pas besoin de générer de Certificates ni de saisir des Devices.

  • Un nouveau développeur rejoint l’équipe

Il va ajouter son appareil dans les Devices, générer son Certificate (Development) puis modifier le Provisioning Profile (Development) pour y cocher son certificat et son appareil. Il modifiera aussi le Provisioning Profile (Ad-Hoc) pour cocher son appareil.

Remarques : À chaque création ou modification, on pensera à installer la clé privée des certificats et les profils sur les machines qui en auront besoin. Certaines étapes peuvent être automatisées par des outils tels que Fastlane et Codemagic, ou par Xcode.

Les comptes et programmes Apple

Je termine cette épopée en remontant à la surface. Respirons, c’est presque terminé. Il ne nous reste plus qu’à jeter un coup d'œil sur les types de compte qui existent et ce qu’ils permettent.

  • Compte développeur

On s’enregistre en créant/utilisant une Apple ID. C’est gratuit et accessible à tous. On a accès aux outils comme Xcode et les simulateurs. On peut installer l’application sur un appareil relié à notre poste. On ne fait que du développement, aucune distribution possible. On ne peut pas créer de Certificate, de Profile ou autre.

  • Apple Developer Program

On souscrit au programme pour 99$ par an, en tant qu’individu ou entreprise. Notre compte développeur aura accès à la distribution Ad-Hoc et App Store. On aura aussi accès à l’App Store Connect. C’est le programme auquel on souscrit dans une immense majorité des cas. On peut tout faire sauf déployer sur un store interne.

  • Apple Developer Enterprise Program

On souscrit au programme pour 299$ par an en tant que grande entreprise. Notre compte développeur aura accès à la distribution In-House - c’est seulement pour déployer sur un store interne. L’accès à ce programme est contraint par plusieurs conditions et nécessite une vérification d’Apple. On doit avoir un réel besoin auquel le programme classique ne peut répondre.

Quelques ressources

Petit cadeau de fin, j’ai fouillé les internets d’Apple pour faire remonter des liens utiles. Les voici :