L'autorisation d'accès aux contacts est un mécanisme des systèmes d'exploitation mobiles qui nécessite le consentement explicite de l'utilisateur avant de lire le carnet d'adresses de l'appareil. Sous iOS, l'accès aux contacts s'effectue via CNContactStore, tandis que sous Android, il utilise l'API Contacts et le système d'autorisations runtime. Selon Apple Developer Documentation, 2025, à partir d'iOS 18, toutes les applications doivent utiliser l'API unifiée Contacts Access API. L'implémentation correcte de la demande d'autorisation augmente les chances d'approbation par la modération des magasins d'applications.
Points clés
L'autorisation d'accès aux contacts est un mécanisme du système d'exploitation qui protège le carnet d'adresses de l'utilisateur contre la lecture non autorisée par des applications tierces. Dans les systèmes d'exploitation mobiles, les contacts sont considérés comme des données sensibles car ils contiennent des noms, des numéros de téléphone, des adresses e-mail et des photos de personnes de l'entourage de l'utilisateur.
Sous iOS, l'autorisation est régie par le framework Contacts et la classe CNContactStore. L'utilisateur voit une boîte de dialogue système lors de la première demande d'accès, où il peut choisir d'accorder ou de refuser l'accès. Sous Android, la protection repose sur le système d'autorisations runtime : l'application déclare READ_CONTACTS dans le manifeste et le demande lors de l'exécution via ActivityResultLauncher ou un fragment gérant le résultat.
Selon Statista (2025), plus de 68 % des utilisateurs iOS et 54 % des utilisateurs Android refusent l'accès aux contacts lors de la première demande. Cela signifie que le développeur doit non seulement implémenter correctement la demande, mais aussi expliquer à l'utilisateur pourquoi l'accès est nécessaire.
Norme industrielle — demander l'accès uniquement lorsque la fonctionnalité est réellement nécessaire, pas au premier lancement. Cette approche réduit le taux de refus et améliore l'expérience utilisateur.
Dans l'écosystème Apple, l'accès aux contacts est régulé par le framework Contacts, introduit dans iOS 9. La classe CNContactStore fournit des méthodes pour demander l'autorisation et effectuer des opérations de lecture et d'écriture. Lors du premier appel à requestAccess(for:), le système affiche une boîte de dialogue native expliquant la raison de l'accès.
À partir d'iOS 17, Apple a introduit le mode d'accès à un seul contact. L'utilisateur peut sélectionner un contact dans le carnet d'adresses et le partager avec l'application sans révéler l'intégralité de la base de données. Ce mode est implémenté via CNContactPickerViewController et ne nécessite pas d'appeler requestAccess(for:).
Il est important que le développeur comprenne : si une application demande un accès complet mais n'a fonctionnellement besoin que d'un seul contact, les modérateurs de l'App Store peuvent rejeter la build. Selon les Apple App Review Guidelines (2025), la section 5.1.1 exige explicitement la quantité minimale de données nécessaire.
Avec la sortie d'iOS 18, Apple a renforcé les exigences relatives au Privacy Manifest — le fichier privacy.xcprivacy dans lequel le développeur déclare la raison de l'accès aux données protégées. Pour les contacts, la clé NSContactsUsageDescription est utilisée avec un texte localisé affiché dans la boîte de dialogue système.
Sans privacy manifest correct, l'application ne peut pas passer la modération d'App Store Connect. Le texte de description doit être spécifique : pas « Pour améliorer les performances », mais « Pour trouver des amis par numéro de téléphone ».
Sous Android, l'accès aux contacts est protégé par l'autorisation READ_CONTACTS, qui appartient à la catégorie dangereuse — elle doit être demandée lors de l'exécution, pas seulement lors de l'installation. Le mécanisme des autorisations runtime a été introduit dans Android 6.0 (API 23) et reste le principal moyen de protéger les données sensibles.
L'autorisation READ_CONTACTS est déclarée dans le manifeste via la balise uses-permission, et demandée dans le code via ActivityResultLauncher ou un fragment avec onRequestPermissionsResult. L'utilisateur peut refuser la demande ou sélectionner « Ne plus demander », après quoi l'application doit traiter correctement le refus.
À partir d'Android 14 (API 34), le comportement des autorisations runtime a changé : après deux refus consécutifs, le système d'exploitation définit automatiquement le drapeau neverAskAgain. Selon Google Developer Documentation (2024), le développeur doit vérifier le statut via shouldShowRequestPermissionRationale avant de redemander.
Pour lire les contacts, Android utilise un ContentProvider appelé ContactsContract. Il s'agit d'une base de données structurée accessible via ContentResolver. Les données sont organisées en plusieurs tables : Contacts (contacts), RawContacts (enregistrements bruts de différents comptes), Data (informations détaillées : téléphones, e-mails, adresses).
La requête vers ContactsContract s'effectue via l'URI ContactsContract.Contacts.CONTENT_URI. Le développeur doit demander le minimum de colonnes et utiliser une projection pour filtrer les champs — cela accélère l'exécution de la requête et réduit la consommation mémoire.
L'implémentation pratique de la demande d'accès aux contacts diffère entre iOS et Android. Voici des exemples concrets en Swift et Kotlin avec la gestion de tous les états possibles de l'autorisation.
Sous iOS, la demande s'effectue via la méthode requestAccess de la classe CNContactStore. Le résultat est retourné dans une closure avec une valeur booléenne et une erreur optionnelle. L'exemple ci-dessous illustre le cycle complet de demande avec la gestion du statut.
import Contacts
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
if granted {
print("Accès aux contacts accordé")
// Exécution des opérations sur les contacts
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
try? store.enumerateContacts(with: request) { contact, stop in
print("\(contact.givenName) \(contact.familyName)")
}
} else {
print("Accès refusé : \(error?.localizedDescription ?? "erreur inconnue")")
}
}
Sous Android, la demande s'effectue via ActivityResultLauncher avec le contrat RequestPermission. L'exemple ci-dessous montre le travail avec ContactsContract.ContentProvider après l'obtention de l'autorisation.
val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
val uri = ContactsContract.Contacts.CONTENT_URI
val cursor = contentResolver.query(uri, null, null, null, null)
cursor?.use {
val nameIndex = it.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
while (it.moveToNext()) {
val name = it.getString(nameIndex)
Log.d("Contacts", "Contact : $name")
}
}
} else {
// Expliquer à l'utilisateur la raison du besoin d'accès
showRationaleDialog()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissionLauncher.launch(android.Manifest.permission.READ_CONTACTS)
}
Les développeurs d'applications mobiles expérimentés suivent un ensemble de pratiques éprouvées lorsqu'ils travaillent avec l'autorisation d'accès aux contacts. Ces règles aident à passer la modération des magasins d'applications et à maintenir la confiance des utilisateurs. Suivre les meilleures pratiques simplifie considérablement le processus de publication et de maintenance.
Ne demandez jamais l'accès aux contacts au premier lancement de l'application. La première demande doit avoir lieu dans le contexte d'une fonctionnalité spécifique : rechercher des amis, inviter des participants, importer des contacts. Un utilisateur qui comprend la raison de la demande accepte 2 à 3 fois plus souvent, selon les recherches d'Apptentive (2024).
Si la fonctionnalité nécessite uniquement l'accès à un seul contact, utilisez CNContactPickerViewController sur iOS ou une intention implicite ACTION_PICK sur Android. Ces méthodes ne nécessitent pas d'autorisation préalable et permettent à l'utilisateur de sélectionner lui-même un enregistrement sans révéler l'intégralité du carnet d'adresses à l'application.
L'application doit gérer correctement les situations où l'utilisateur refuse l'accès. Sur iOS, vérifiez le statut via CNContactStore.authorizationStatus(for:) et dirigez l'utilisateur vers les Réglages si nécessaire. Sur Android, utilisez shouldShowRequestPermissionRationale pour afficher une explication supplémentaire avant de redemander.
N'affichez jamais une deuxième boîte de dialogue immédiatement après un refus — cela est perçu comme agressif et réduit la note de l'application. Meilleure pratique : après un certain temps, affichez un écran avec une explication et un bouton « Aller aux paramètres » qui ouvre l'écran des autorisations système via une intention. Testez le scénario de refus sur des appareils réels — les simulateurs ne reproduisent pas toujours correctement le comportement des boîtes de dialogue d'autorisation système.
Foire aux questions
Les applications demandent l'accès aux contacts pour des fonctions telles que la recherche d'amis, l'invitation de participants, le remplissage automatique de formulaires et la synchronisation avec le serveur. Exemples : les messageries recherchent des contacts par numéro de téléphone, les applications CRM importent des clients.
L'accès à un seul contact (iOS 17+) via CNContactPickerViewController permet à l'utilisateur de sélectionner un contact sans révéler l'intégralité du carnet d'adresses. L'accès complet permet à l'application de lire tous les contacts de l'appareil via CNContactStore. L'accès à un seul contact est plus sûr et ne nécessite pas de spécifier NSContactsUsageDescription dans le privacy manifest.
Sur iOS, allez dans Réglages — Confidentialité et sécurité — Contacts et désactivez l'accès pour l'application concernée. Sur Android, ouvrez Paramètres — Applications — sélectionnez l'application — Autorisations — Contacts et choisissez « Refuser ».
Le Privacy Manifest (fichier privacy.xcprivacy) est un document obligatoire pour iOS 18+, dans lequel le développeur déclare les raisons de l'accès aux données protégées, y compris les contacts. La clé NSContactsUsageDescription contient une description localisée affichée dans la boîte de dialogue de demande d'autorisation système.
Android classe READ_CONTACTS comme une autorisation dangereuse car elle donne accès aux données personnelles de l'utilisateur. Le mécanisme d'autorisations runtime, introduit dans Android 6.0, exige un consentement explicite lors de l'exécution, pas seulement lors de l'installation de l'application.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi