Дозвіл на доступ до контактів — це механізм мобільних ОС, що вимагає явної згоди користувача перед читанням записної книжки пристрою. В iOS доступ до контактів здійснюється через CNContactStore, а на Android — через Contacts API та систему runtime permissions. За даними Apple Developer Documentation, 2025, з iOS 18 всі додатки зобов'язані використовувати уніфікований Contacts Access API. Правильна реалізація запиту дозволу підвищує шанси на схвалення модерацією магазинів додатків.
Головне
Дозвіл на доступ до контактів — це механізм операційної системи, який захищає записну книжку користувача від несанкціонованого читання сторонніми додатками. У мобільних ОС контакти вважаються конфіденційними даними, оскільки містять імена, номери телефонів, адреси електронної пошти та фотографії людей з оточення користувача.
На iOS дозвіл регулюється фреймворком Contacts та класом CNContactStore. Користувач бачить системний діалог при першому запиті доступу, де може вибрати надати доступ або відхилити запит. На Android захист будується на системі runtime permissions: додаток вказує READ_CONTACTS у маніфесті та запитує його під час виконання через ActivityResultLauncher або фрагмент з обробкою результату.
За даними Statista (2025), понад 68% користувачів iOS та 54% користувачів Android відмовляють у доступі до контактів при першому запиті додатка. Це означає, що розробнику необхідно не лише коректно реалізувати запит, але й пояснити користувачеві причину необхідності доступу.
Галузевий стандарт — запитувати доступ лише в момент, коли функціональність дійсно потрібна, а не при першому запуску. Такий підхід знижує відсоток відмов та покращує користувацький досвід.
В екосистемі Apple доступ до контактів регулюється фреймворком Contacts, представленим в iOS 9. Клас CNContactStore надає методи для запиту дозволу та виконання операцій читання та запису. При першому виклику requestAccess(for:) система відображає нативний діалог з поясненням причини доступу.
Починаючи з iOS 17, Apple ввела режим одноразового доступу. Користувач може вибрати один контакт із записної книжки та передати його додатку, не розкриваючи всю базу. Режим реалізовано через CNContactPickerViewController і не вимагає виклику requestAccess(for:).
Розробнику важливо розуміти: якщо додаток запитує повний доступ, а функціонально йому достатньо одного контакту, модератори App Store можуть відхилити збірку. За даними Apple App Review Guidelines (2025), розділ 5.1.1 явно вимагає мінімально необхідного обсягу даних.
З виходом iOS 18 Apple посилила вимоги до Privacy Manifest — файлу privacy.xcprivacy, в якому розробник декларує причину доступу до захищених даних. Для контактів використовується ключ NSContactsUsageDescription з локалізованим текстом, що відображається в системному діалозі.
Без коректного privacy manifest додаток не проходить модерацію App Store Connect. Текст опису має бути конкретним: не «Для покращення роботи», а «Для пошуку друзів за номером телефону».
На Android доступ до контактів захищений дозволом READ_CONTACTS, що належить до категорії небезпечних — його необхідно запитувати під час виконання, а не тільки при встановленні. Механізм runtime permissions був введений в Android 6.0 (API 23) і залишається основним способом захисту конфіденційних даних.
Дозвіл READ_CONTACTS вказується в маніфесті через тег uses-permission, а запитується в коді через ActivityResultLauncher або фрагмент з onRequestPermissionsResult. Користувач може відхилити запит або вибрати опцію «Більше не питати», після чого додаток повинен коректно обробити відмову.
Починаючи з Android 14 (API 34), поведінка runtime permissions змінилася: при відхиленні двох послідовних запитів ОС автоматично встановлює прапорець neverAskAgain. За даними Google Developer Documentation (2024), розробник повинен перевіряти статус через shouldShowRequestPermissionRationale перед повторним запитом.
Для читання контактів Android використовує ContentProvider під назвою ContactsContract. Це структурована база даних, доступна через ContentResolver. Дані організовані в кілька таблиць: Contacts (контакти), RawContacts (сирі записи з різних акаунтів), Data (детальна інформація: телефони, email, адреси).
Запит до ContactsContract виконується через URI ContactsContract.Contacts.CONTENT_URI. Розробнику необхідно запитувати мінімум колонок та використовувати проекцію для фільтрації полів — це прискорює виконання запиту та знижує споживання пам'яті.
Практична реалізація запиту доступу до контактів відрізняється на iOS та Android. Нижче наведено конкретні приклади на Swift та Kotlin з обробкою всіх можливих станів дозволу.
В iOS запит виконується через метод requestAccess класу CNContactStore. Результат повертається в замиканні з булевим значенням та опціональною помилкою. Приклад нижче демонструє повний цикл запиту з обробкою статусу.
import Contacts
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
if granted {
print("Доступ до контактів отримано")
// Виконання операцій з контактами
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("Доступ відхилено: \(error?.localizedDescription ?? "неизвестная ошибка")")
}
}
На Android запит виконується через ActivityResultLauncher з контрактом RequestPermission. У прикладі нижче показана робота з ContactsContract.ContentProvider після отримання дозволу.
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", "Контакт: $name")
}
}
} else {
// Пояснити користувачеві причину необхідності доступу
showRationaleDialog()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissionLauncher.launch(android.Manifest.permission.READ_CONTACTS)
}
Досвідчені розробники мобільних додатків слідують набору перевірених практик при роботі з дозволом на доступ до контактів. Ці правила допомагають пройти модерацію магазинів додатків та зберегти довіру користувачів. Дотримання найкращих практик суттєво спрощує процес публікації та підтримки додатка.
Ніколи не запитуйте доступ до контактів при першому запуску додатка. Перший запит має відбуватися в контексті конкретної функції: пошук друзів, запрошення учасників, імпорт контактів. Користувач, який розуміє причину запиту, погоджується в 2–3 рази частіше, як показують дослідження Apptentive (2024).
Якщо функціональності достатньо для доступу до одного контакту — використовуйте CNContactPickerViewController на iOS або implicit intent ACTION_PICK на Android. Ці методи не вимагають попереднього дозволу та дозволяють користувачеві самостійно вибрати запис, не розкриваючи всю записну книжку додатку.
Додаток повинен коректно обробляти ситуацію, коли користувач відхилив запит. На iOS перевіряйте статус через CNContactStore.authorizationStatus(for:) та направляйте користувача в Налаштування при необхідності. На Android використовуйте shouldShowRequestPermissionRationale для показу додаткового пояснення перед повторним запитом.
Ніколи не показуйте повторний діалог одразу після відмови — це сприймається як агресія та знижує рейтинг додатка. Найкраща практика: через деякий час показати екран з поясненням та кнопкою «Перейти до налаштувань», яка відкриває системний екран дозволів через Intent. Тестуйте сценарій відмови на реальних пристроях — симулятори не завжди коректно відтворюють поведінку системних діалогів дозволів.
Часті запитання
Додатки запитують доступ до контактів для функцій пошуку друзів, запрошення учасників, автоматичного заповнення форм та синхронізації з сервером. Приклади: месенджери шукають контакти за номером телефону, CRM-додатки імпортують клієнтів.
Одноразовий доступ (iOS 17+) через CNContactPickerViewController дозволяє користувачеві вибрати один контакт без розкриття всієї записної книжки. Повний доступ дає додатку читати всі контакти пристрою через CNContactStore. Одноразовий доступ безпечніший та не вимагає вказівки NSContactsUsageDescription в privacy manifest.
На iOS перейдіть в Налаштування — Конфіденційність та безпека — Контакти та вимкніть доступ для конкретного додатка. На Android відкрийте Налаштування — Додатки — виберіть додаток — Дозволи — Контакти та виберіть «Відхилити».
Privacy Manifest (файл privacy.xcprivacy) — обов'язковий документ для iOS 18+, в якому розробник декларує причини доступу до захищених даних, включаючи контакти. Ключ NSContactsUsageDescription містить локалізований опис, що відображається в системному діалозі запиту дозволу.
Android класифікує READ_CONTACTS як небезпечний дозвіл, оскільки він надає доступ до персональних даних користувача. Механізм runtime permissions, введений в Android 6.0, вимагає явної згоди під час виконання, а не тільки при встановленні додатка.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також