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 је уско повезан са моделом runtime permissions у 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, Health. 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). Ова пракса побољшава корисничко искуство и повећава вероватноћу да ће корисник укључити приступ.
Не приказујте alert са захтевом да се укључи приступ одмах након одбијања — дајте кориснику прилику да разуме зашто му ова функција може затребати. Боље је приказати објашњење при покушају коришћења функционалности која захтева дату дозволу. UX Movement (2023) препоручује приказ екрана са објашњењем након 2-3 сесије од одбијања.
func showSettingsAlert(for feature: String) {
let alert = UIAlertController(
title: "Доступ к \(feature)",
message: "Дозволите приступ у Подешавањима, "
+ "да бисте користили ову функцију",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(
title: "Отвори Подешавања",
style: .default
) { _ in
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
})
alert.addAction(UIAlertAction(
title: "Не сада", style: .cancel
))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
}
Недостатак обавезног кључа Usage Description доводи до тренутног пада апликације при првом позиву одговарајућег API-ја. Ово није Xcode упозорење, већ runtime crash са изузетком NSInvalidArgumentException и поруком у конзоли: „This app has crashed because it attempted to access privacy-sensitive data without a usage description".
iOS проверава присуство кључа NS*UsageDescription у Info.plist-у при првом позиву API-ја за заштићени ресурс. Ако кључ недостаје, систем одмах прекида апликацију сигналом SIGABRT. Ово се дешава чак и на уређајима за отклањање грешака — Xcode приказује изузетак у логу, али га дебагер не хвата као тачку прекида.
Пад се појављује на правим уређајима и симулатору. Једини начин да се избегне је додавање кључа пре позива API-ја. Статички анализатор Xcode-а не упозорава увек на недостатак кључа, посебно ако се API позива преко трећих SDK-ова. TestFlight тестери ће такође видети пад, што може довести до негативних рецензија.
Посебна ситуација са iOS 17+: Apple је увео додатну проверу за приступ клипборду (UIPasteboard). Ако апликација чита клипборд без експлицитне радње корисника, iOS приказује банер са упозорењем, чак и ако кључ Usage Description постоји. За клипборд није потребан посебан кључ, али Apple препоручује минимизирање аутоматског читања.
Поред runtime пада, недостатак кључа може бити разлог за одбијање апликације при модерацији. Apple проверава Info.plist у фази ревизије и може одбити буилд ако открије позиве API-ја без одговарајућих кључева. Xcode не блокира архивирање, али App Store Connect може вратити грешку при обради бинарног фајла.
Ако апликација не користи ресурс директно, али то чини трећи SDK (нпр. аналитички SDK захтева IDFA), програмер и даље мора да дода одговарајући кључ. Apple проверава све позиве API-ја у бинарном фајлу, укључујући код из статичких и динамичких библиотека. Грешка „Missing Info.plist key" је један од најчешћих разлога одбијања ажурирања.
Често постављана питања
Да, ако трећи SDK позива API приступа ресурсу (камера, геолокација, фото), кључ је обавезан. iOS проверава цео бинарни фајл, укључујући зависности, и руши апликацију при недостатку кључа.
Не, сваки заштићени ресурс захтева посебан кључ. На пример, NSCameraUsageDescription не замењује NSMicrophoneUsageDescription. Систем тражи одређени кључ по имену при позиву сваког API-ја.
Прикажите екран са објашњењем како укључити приступ преко Подешавања → Апликација и понудите дугме за отварање подешавања апликације. Системски дијалог се не може поново програмски позвати.
Направите InfoPlist.strings датотеку за сваки језик и наведите преводе. iOS аутоматски користи језик уређаја при приказу дијалога. Xcode такође подржава основну локализацију Info.plist-а.
iOS симулатор у потпуности репродукује понашање уређаја, укључујући проверу Usage Description. Ако кључ недостаје, симулатор ће такође прекинути апликацију са изузетком. Ово је очекивано понашање за отклањање грешака.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође