Info.plist Usage Description — це обов'язкові ключі у файлі Info.plist застосунку iOS, які містять текст, що відображається користувачеві під час запиту доступу до системних функцій: камери, мікрофона, геолокації, фотоальбому та інших. Кожен такий ключ має префікс NS*UsageDescription і надає рядок, який пояснює причину запиту доступу. Згідно з Apple Information Property List Guide, відсутність ключа для запитаного ресурсу призводить до негайного крашу застосунку.
Головне
Info.plist Usage Description — це рядкові значення ключів із префіксом NS*UsageDescription, які визначають текст системного діалогу під час запиту доступу до захищених ресурсів iOS. Коли застосунок вперше викликає API, що потребує дозволу користувача (наприклад, AVCaptureDevice для камери), iOS показує діалог із цим текстом і кнопками дозволу або відмови.
Текст опису — єдине, що розробник може контролювати в системному діалозі. Заголовок діалогу «<Назва застосунку> хоче отримати доступ до [ресурсу]» генерується iOS автоматично на основі типу запитаного ресурсу. Розробник не може змінити заголовок, кнопки або зовнішній вигляд — лише текст пояснення.
Usage Description тісно пов'язаний із моделлю дозволів часу виконання в iOS. Користувач надає дозвіл на один запит, який може бути відкликано пізніше через Налаштування. При повторному запиті діалог не показується — застосунок повинен перевіряти статус дозволу та реагувати відповідним чином.
Apple наполегливо рекомендує вказувати в описі конкретну причину запиту доступу. Наприклад, «Для зйомки фотографій профілю» краще, ніж «Для доступу до камери». Конкретні тексти підвищують довіру користувача та відсоток наданих дозволів. За даними Localytics (2023), кастомні описи збільшують згоду на 15-25% порівняно із загальними формулюваннями.
Не плутайте NS*UsageDescription із ATT (App Tracking Transparency). Usage Description — це запит доступу до системних ресурсів (камера, геолокація, фото), а ATT — запит на відстеження (доступ до IDFA). ATT використовує окремий фреймворк AppTrackingTransparency і ключ NSUserTrackingUsageDescription, який не належить до NS*UsageDescription.
Спільне між ними — обидва використовують системний діалог із текстом, який застосунок не може модифікувати. Різниця в тому, що Usage Description працює на рівні ресурсів, а ATT — на рівні ідентифікатора пристрою. Ключі NS*UsageDescription були введені в iOS 6, ATT — в iOS 14.5.
З кожним випуском iOS Apple додавала нові захищені ресурси та відповідні ключі. iOS 6: контакти, календар, нагадування, фото. iOS 7: мікрофон. iOS 8: HomeKit, здоров'я. iOS 10: медіатека, Siri. iOS 11: NFC. iOS 14: відстеження (ATT). iOS 17: доступ до буфера обміну (потребує додаткового підтвердження).
Важливо: якщо застосунок використовує API, що з'явилося в певній версії iOS, але мінімальна підтримувана версія нижча, ключ все одно обов'язковий. iOS перевіряє наявність ключа перед першим викликом API, незалежно від версії, на якій запущено застосунок.
Повний список ключів залежить від того, які функції використовує застосунок. Розглянемо 14 основних ключів, які найчастіше потрібні в мобільних застосунках.
Ключ NSCameraUsageDescription обов'язковий при доступі до камери через AVCaptureDevice або UIImagePickerController із джерелом .camera. Ключ NSMicrophoneUsageDescription — при записі аудіо через AVAudioRecorder або при зйомці відео зі звуком. Обидва ключі часто потрібні разом, якщо застосунок знімає відео.
Ключ NSPhotoLibraryUsageDescription — при читанні фото та відео з медіатеки користувача через PHPicker або UIImagePickerController. Ключ NSPhotoLibraryAddUsageDescription — якщо застосунок лише зберігає фото, але не читає їх. Перший запитує доступ на читання, другий — лише на запис.
Ключ NSLocationWhenInUseUsageDescription — доступ до геолокації, коли застосунок активний (на екрані). NSLocationAlwaysAndWhenInUseUsageDescription — доступ завжди (включаючи фоновий режим). iOS потребує обидва ключі, якщо потрібен завждишній доступ: спочатку WhenInUse, потім Always.
Ключі NSLocationTemporaryUsageDescription і NSLocationPreciseUsageDescription — додаткові ключі для запиту тимчасового доступу або точної геолокації. Точна локація потребує окремого дозволу, і користувач може ввімкнути лише приблизну.
| Ключ | Ресурс | Доступний з iOS |
|---|---|---|
| NSCameraUsageDescription | Камера | 6.0 |
| NSMicrophoneUsageDescription | Мікрофон | 7.0 |
| NSPhotoLibraryUsageDescription | Медіатека (читання) | 6.0 |
| NSPhotoLibraryAddUsageDescription | Медіатека (запис) | 11.0 |
| NFCReaderUsageDescription | NFC | 11.0 |
Ключ NSContactsUsageDescription — доступ до контактів користувача через CNContactStore. NSCalendarsUsageDescription — доступ до календаря для читання та створення подій. NSRemindersUsageDescription — доступ до нагадувань. NSBluetoothAlwaysUsageDescription — доступ до Bluetooth у фоні (наприклад, для BLE-пристроїв).
Ключ NSHealthShareUsageDescription — доступ до читання даних HealthKit. NSHealthUpdateUsageDescription — доступ до запису даних у HealthKit. Обидва обов'язкові, якщо застосунок працює зі здоров'ям. Apple ретельно перевіряє застосунки, що використовують HealthKit, і може відхилити, якщо опис використання не відповідає функціоналу.
Текст в Usage Description має бути конкретним, правдивим і лаконічним. Apple дає рекомендації щодо формулювань, а модератори перевіряють їх відповідність функціональності.
Хороший опис складається з трьох частин: що саме робить застосунок із ресурсом, навіщо це потрібно користувачеві та яка вигода користувачеві від надання доступу. Приклад: «Для зйомки фотографій профілю та їх завантаження в анкету». Уникайте загальних фраз: «Для покращення роботи застосунку» не пояснює, навіщо потрібна камера.
Apple забороняє оманливі описи. Якщо написано «Для зйомки фото», але застосунок також записує відео, це може бути розцінено як обман. Модератор може відхилити застосунок або запросити роз'яснення. В iOS 17 Apple додала автоматичну перевірку: опис має містити ключові слова, що відповідають запитаному ресурсу.
Локалізація: опис має бути перекладено всіма мовами, які підтримує застосунок. Якщо застосунок доступний 10 мовами, кожен ключ Usage Description повинен мати переклади у файлах Localizable.strings або в InfoPlist.strings. Apple рекомендує використовувати InfoPlist.strings для локалізації ключів Info.plist.
Для локалізації Usage Description не потрібно дублювати Info.plist на кожну мову. Створіть файл InfoPlist.strings у кожному мовному каталозі та вкажіть значення ключів. iOS автоматично підставить потрібну мову в діалог. Xcode підтримує базову локалізацію для Info.plist починаючи з версії 14.
<!-- InfoPlist.strings (Russian) -->
"NSCameraUsageDescription" =
"Для сканування QR-кодів";
"NSPhotoLibraryUsageDescription" =
"Для завантаження зображень у профіль";
"NSLocationWhenInUseUsageDescription" =
"Для відображення найближчих магазинів на карті";
Правильна реалізація Usage Description включає додавання ключів до Info.plist, перевірку статусу дозволу в коді та обробку відмови.
У Xcode відкрийте Info.plist, наведіть на рядок і натисніть «+». Введіть назву ключа (наприклад, NSCameraUsageDescription) та вкажіть рядок опису. Xcode автодоповнює імена ключів, що знижує ризик помилок. Після додавання перескладіть проєкт і перевірте, що ключ відображається в підсумковому бінарнику.
Важливо: ключі чутливі до регістру. NSCameraUsageDescription — вірно, NSCamerausagedescription — помилка. Невірний ключ ігнорується, і застосунок впаде при виклику API. Використовуйте копіювання з документації Apple або автодоповнення Xcode для виключення помилок.
import AVFoundation
import Photos
final class PermissionManager {
static func checkCameraPermission() {
let status = AVCaptureDevice.authorizationStatus(for: .video)
switch status {
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { granted in
print("Camera access: \(granted)")
}
case .denied:
print("Camera access denied")
case .authorized:
print("Camera access authorized")
@unknown default:
break
}
}
static func requestPhotoLibraryAccess() {
PHPhotoLibrary.requestAuthorization { status in
print("Photo library status: \(status.rawValue)")
}
}
}
Якщо користувач відмовив у доступі, застосунок не повинен повторно викликати системний діалог — це неможливо. Натомість покажіть інформаційний екран із поясненням, як увімкнути доступ через Налаштування, і кнопку «Відкрити налаштування» (UIApplicationOpenSettingsURLString). Така практика підвищує користувацький досвід і ймовірність того, що користувач увімкне доступ.
Не показуйте алерт із проханням увімкнути доступ одразу після відмови — дайте користувачеві можливість зрозуміти, чому йому може знадобитися ця функція. Краще показати пояснення при спробі використання функціональності, яка потребує цього дозволу. UX Movement (2023) рекомендує показувати екран пояснення через 2-3 сесії після відмови.
func showSettingsAlert(for feature: String) {
let alert = UIAlertController(
title: "Доступ к \(feature)",
message: "Allow access in Settings, "
+ "to use this feature",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(
title: "Open Settings",
style: .default
) { _ in
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
})
alert.addAction(UIAlertAction(
title: "Not now", style: .cancel
))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
}
Відсутність обов'язкового ключа Usage Description призводить до негайного крашу застосунку при першому виклику відповідного API. Це не попередження Xcode, а краш часу виконання із винятком NSInvalidArgumentException і повідомленням у консоль: «Цей застосунок впав, оскільки він намагався отримати доступ до конфіденційних даних без опису використання».
iOS перевіряє наявність ключа NS*UsageDescription в Info.plist при першому виклику API для захищеного ресурсу. Якщо ключ відсутній, ОС негайно завершує застосунок із сигналом SIGABRT. Це відбувається навіть на пристроях із налагодженням — Xcode показує виняток у лозі, але налагоджувач не ловить його як точку зупину.
Краш відтворюється на реальних пристроях і симуляторі. Єдиний спосіб уникнути — додати ключ до виклику API. Статичний аналізатор Xcode не завжди попереджає про відсутність ключа, особливо якщо API викликається через сторонні SDK. TestFlight тестери також побачать краш, що може призвести до негативних відгуків.
Особлива ситуація з iOS 17+: Apple ввела додаткову перевірку для доступу до буфера обміну (UIPasteboard). Якщо застосунок читає буфер обміну без явної дії користувача, iOS показує банер із попередженням, навіть якщо ключ Usage Description присутній. Для буфера обміну окремий ключ не потрібен, але Apple рекомендує мінімізувати автоматичне читання.
Окрім крашу часу виконання, відсутність ключа може стати причиною відхилення застосунку при модерації. Apple перевіряє Info.plist на етапі рев'ю і може відхилити збірку, якщо виявить виклики API без відповідних ключів. Xcode не блокує архівацію, але App Store Connect може повернути помилку при обробці бінарника.
Якщо застосунок не використовує ресурс безпосередньо, але сторонній SDK робить це (наприклад, SDK аналітики запитує IDFA), розробник все одно повинен додати відповідний ключ. Apple перевіряє всі виклики API в бінарнику, включаючи код зі статичних і динамічних бібліотек. Помилка «Відсутній ключ Info.plist» — одна з найчастіших причин відхилення оновлень.
Часто задавані питання
Так, якщо сторонній SDK викликає API доступу до ресурсу (камера, геолокація, фото), ключ обов'язковий. iOS перевіряє бінарник цілком, включаючи залежності, і крашить застосунок при відсутності ключа.
Ні, кожен захищений ресурс потребує окремого ключа. Наприклад, NSCameraUsageDescription не замінює NSMicrophoneUsageDescription. Система шукає конкретний ключ за ім'ям при виклику кожного API.
Покажіть екран із поясненням, як увімкнути доступ через Налаштування → Застосунок, і запропонуйте кнопку для відкриття налаштувань застосунку. Системний діалог не може бути викликано повторно програмно.
Створіть файл InfoPlist.strings для кожної мови та вкажіть переклади. iOS автоматично використовує мову пристрою при показі діалогу. Xcode також підтримує базову локалізацію Info.plist.
Симулятор iOS повністю відтворює поведінку пристрою, включаючи перевірку Usage Description. Якщо ключ відсутній, симулятор також завершить застосунок із винятком. Це очікувана поведінка для налагодження.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також