Publier une app sur les deux stores en 2026 n'est plus une formalité — c'est un chantier parallèle qui commence 4 semaines avant le lancement et se rejoue à chaque version. Ce guide donne la chronologie exacte, les commandes concrètes, et les pièges qu'on paie deux fois si on les découvre en production.
Chronologie recommandée
J-30 : comptes développeur. Créer Apple Developer Program et Google Play Console. Compter 2 à 5 jours ouvrés pour la vérification DUNS Apple (entreprise) et 24 à 48 h pour la vérification d'identité Google.
J-21 : setup technique. Certificats iOS (Distribution + Provisioning App Store), Play App Signing (upload keystore), pipelines CI/CD (EAS Build ou GitHub Actions + fastlane).
J-14 : assets et métadonnées. Icônes, captures, feature graphic, textes de description dans les deux locales cibles, politique de confidentialité en ligne, Data Safety form rempli, Privacy Manifest ajouté.
J-7 : première soumission. Upload build → TestFlight (interne + externe si besoin) → 48 h de test sur canaux internes → Submit for Review côté Apple + Closed Testing puis Production côté Google.
J-0 : lancement. Approbation reçue, phased release activée, monitoring des crash reports, réponse aux premiers avis.
J+7 à J+30 : itération. Version 1.0.1 pour les correctifs remontés dans la semaine, planifier version 1.1 avec les demandes utilisateurs.
Setup Apple : le détail
Créer un App ID.
Dans developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → nouveau App ID de type App :
- Bundle ID : reverse-DNS (ex.
com.mag-cie.myopenspot). IRRÉVERSIBLE — changer = nouvelle app, perte des reviews et téléchargements. Choisir avec soin. - Capabilities à activer selon le besoin (Push Notifications, Sign in with Apple, In-App Purchase, Associated Domains…). Activable après, mais nécessite nouveau provisioning profile.
Créer le certificat de distribution.
Certificates → nouveau → Apple Distribution (nouveau format 2020+, remplace iOS Distribution). Générer un CSR depuis Keychain Access sur Mac, uploader, télécharger le .cer. À garder précieusement — expiration 12 mois, à renouveler avant.
Créer le provisioning profile App Store.
Profiles → nouveau → App Store → sélectionner App ID + certificat. Télécharger le .mobileprovision, l'installer dans Xcode (ou uploader dans EAS credentials).
Configurer l'app dans App Store Connect.
appstoreconnect.apple.com → My Apps → nouveau. Remplir :
- Platform : iOS (+ macOS, tvOS, visionOS si concerné)
- Name : nom affiché sur les stores (30 chars max)
- Primary Language : français ou anglais selon locale principale
- Bundle ID : celui créé précédemment
- SKU : identifiant interne (ex.
myopenspot-ios-2026)
Setup Google Play : le détail
Créer l'app dans Play Console.
play.google.com/console → Créer une application. Remplir :
- Nom
- Langue par défaut
- App ou jeu
- Gratuit ou payant (irréversible côté payant → gratuit)
- Package name (reverse-DNS, IRRÉVERSIBLE)
Activer Play App Signing.
Dans Setup → App Signing. Google gère la signing key finale (celle qui signe les APK distribués). Vous gérez uniquement une "upload key" pour uploader vos AAB.
Générer l'upload keystore :
keytool -genkey -v -keystore upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 -alias upload
Uploader la clé publique (extraction via keytool -export) à Google. Sauvegarder le keystore + mot de passe dans le coffre-fort de l'entreprise ET dans les secrets CI.
Remplir le formulaire Data Safety.
Setup → Data safety. À la main, à mettre à jour à chaque nouvelle version. Structure :
- Data collection : oui/non global
- Data sharing avec tiers : oui/non global
- Pour chaque type de donnée collectée (nom, email, localisation précise, photos, contacts, contenu généré) : catégorie, finalité, obligatoire ou optionnel, partagé oui/non
- Sécurité : chiffrement en transit oui/non, suppression sur demande oui/non, conformité MPO for Kids si applicable
Google confronte ces déclarations à une analyse statique de l'AAB uploadé. Un mismatch (par ex. permission ACCESS_FINE_LOCATION dans le manifest mais formulaire dit "pas de localisation collectée") → warning au minimum, blocage à publication au pire.
Privacy Manifest iOS : obligatoire depuis mai 2024
Créer PrivacyInfo.xcprivacy à la racine du bundle. Format .plist minimal :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeEmailAddress</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>
Ajouter aussi les manifests des SDK tiers (Sentry, RevenueCat, Firebase…) — ces SDK fournissent normalement leur propre PrivacyInfo.xcprivacy embarqué dans leur bundle depuis 2024.
Compilation et upload
iOS avec Xcode natif :
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-archivePath build/MyApp.xcarchive \
archive
xcodebuild -exportArchive \
-archivePath build/MyApp.xcarchive \
-exportPath build/ \
-exportOptionsPlist exportOptions.plist
xcrun altool --upload-app -f build/MyApp.ipa \
--type ios \
--apiKey $ASC_API_KEY --apiIssuer $ASC_API_ISSUER
iOS + Android avec EAS :
eas build --platform all --profile production
eas submit --platform all --latest
Une commande, les deux stores. Configuration dans eas.json :
{
"build": {
"production": {
"ios": { "resourceClass": "m-medium" },
"android": { "buildType": "app-bundle" }
}
},
"submit": {
"production": {
"ios": {
"appleId": "you@company.com",
"ascAppId": "1234567890",
"appleTeamId": "ABCDE12345"
},
"android": {
"serviceAccountKeyPath": "./play-service-account.json",
"track": "internal"
}
}
}
}
TestFlight et Internal Testing
iOS — TestFlight interne (immédiat) : dans App Store Connect → TestFlight → sélectionner la build → activer pour les testeurs internes (jusqu'à 100 membres de votre équipe Apple Developer). Notification push instantanée sur leur iPhone (app TestFlight installée).
iOS — TestFlight externe (24 à 48 h) : ajouter un groupe externe, inviter jusqu'à 10 000 emails ou générer un lien public. Soumettre la build à la revue TestFlight (revue distincte de l'App Store, plus rapide et plus tolérante). Une fois approuvée, les testeurs externes reçoivent l'invitation.
Android — Internal Testing (immédiat) : Play Console → Testing → Internal testing → créer une release → uploader l'AAB → ajouter la liste d'emails Google → publier. Envoyer le lien opt-in aux testeurs. Ils reçoivent la version en 5 à 15 minutes.
Android — Closed Testing (obligatoire pour nouveaux comptes perso) : passer 12 testeurs distincts × 14 jours minimum. Sans cette phase, impossible de sortir en Production.
Soumission et revue
Apple : dans App Store Connect → sélectionner la version → remplir "App Review Information" (identifiants de test si login requis, notes pour Apple : justifier chaque permission sensible, expliquer les fonctions cachées). Cliquer Submit for Review. Suivre le statut dans l'app Apple Developer.
Statuts :
- Waiting for Review : 4 à 24 h
- In Review : 4 à 24 h
- Pending Developer Release / Ready for Sale : approuvé — publier manuellement OU auto-release
Google : promouvoir la release Closed Testing → Production. Google effectue une revue automatique (30 minutes à 24 h) + parfois revue humaine (24 à 72 h). Suivre dans Play Console → Publishing overview.
Gérer un rejet Apple
Le rejet arrive par email + notification dans le Resolution Center. Il contient :
- La guideline citée (ex. 5.1.1)
- Une capture de ce qui pose problème
- Parfois une demande d'information complémentaire
Trois réponses possibles :
-
Répondre avec justification si le rejet est ambigu. Ton factuel, en anglais, expliquer comment votre app respecte la guideline. Apple relit sous 24 à 48 h.
-
Corriger et re-soumettre si le rejet est légitime. Corriger, incrémenter buildNumber, uploader nouvelle build, re-soumettre.
-
Escalader à l'Appeals Board si le rejet est vraiment injustifié. Rare (< 5% des cas), procédure lourde, à réserver aux blocages critiques.
Ne jamais argumenter émotionnellement dans le Resolution Center — la trace reste sur votre compte développeur et pèse sur les revues futures.
Après la publication
Phased Release (iOS) : à activer dans App Store Connect avant de publier. Apple pousse la nouvelle version à 1 %, 2 %, 5 %, 10 %, 20 %, 50 %, 100 % sur 7 jours. En cas de crash massif détecté sur les premiers utilisateurs, possibilité de mettre en pause ou de retirer.
Staged Rollout (Android) : activer manuellement dans Play Console. Démarrer à 10 %, augmenter à 25 %, 50 %, 100 % sur 3 à 5 jours en surveillant les crash reports.
Monitoring : Sentry ou équivalent connecté aux crash reports natifs iOS/Android + JS/React Native. Seuil de tolérance : crash-free sessions > 99.5 %. En-dessous → rollback ou hotfix immédiat.
Réponses aux avis : Apple et Google pénalisent l'inaction. Répondre sous 48 h aux avis 1 à 3 étoiles, remercier brièvement les 4 à 5 étoiles. Un avis répondu peut être modifié à la hausse par l'utilisateur.
Prochaines versions : itérer chaque 2 à 4 semaines pour rester visible dans les stores. Une app sans update depuis 6 mois voit son ranking chuter automatiquement.
Résumé opérationnel
| Étape | Durée réaliste | Bloqueur principal |
|---|---|---|
| Comptes développeur | 2 à 5 jours | DUNS Apple |
| Certificats + signing | 1 à 2 heures | Erreurs de configuration |
| Assets visuels | 4 à 8 heures | Captures cohérentes |
| Métadonnées + Data Safety | 2 à 4 heures | Cohérence code / déclaration |
| Privacy Manifest iOS | 1 à 2 heures | SDK tiers non déclarés |
| Compilation + upload | 30 min | Build number incohérent |
| TestFlight + Internal Testing | 2 à 4 jours | Testeurs indisponibles |
| Revue Apple + Google | 1 à 3 jours | Rejet 2.3, 5.1.1, 4.3 |
| Publication + phased release | 15 min + 7 jours | Crash surveillance |
| Total minimum | 7 à 14 jours | Rejet Apple |
Publier une app, c'est un métier. Ce guide donne la carte. Le terrain, on l'apprend en publiant.
Envie de déléguer ? Voir notre prestation développement d'applications — setup + première publication + transfert de compétence en 3 semaines.