Info.plist Usage Description sono chiavi obbligatorie nel file Info.plist dell'applicazione iOS che contengono il testo visualizzato all'utente quando si richiede l'accesso a funzioni di sistema: fotocamera, microfono, geolocalizzazione, album fotografico e altre. Ogni chiave ha il prefisso NS*UsageDescription e fornisce una stringa che spiega il motivo della richiesta di accesso. Secondo la Guida Information Property List di Apple, l'assenza di una chiave per la risorsa richiesta provoca un arresto immediato dell'applicazione.
Punti chiave
Info.plist Usage Description sono valori stringa delle chiavi con il prefisso NS*UsageDescription che definiscono il testo della finestra di dialogo di sistema quando si richiede l'accesso a risorse protette di iOS. Quando un'app chiama per la prima volta un'API che richiede l'autorizzazione dell'utente (ad esempio, AVCaptureDevice per la fotocamera), iOS mostra una finestra di dialogo con questo testo e i pulsanti Consenti/Nega.
Il testo della descrizione è l'unica cosa che lo sviluppatore può controllare nella finestra di dialogo di sistema. Il titolo della finestra “
Usage Description è strettamente legato al modello delle autorizzazioni in fase di esecuzione in iOS. L'utente concede l'autorizzazione per una richiesta, che può essere revocata successivamente tramite Impostazioni. In una richiesta successiva, la finestra di dialogo non viene più mostrata — l'app deve verificare lo stato dell'autorizzazione e rispondere di conseguenza.
Apple raccomanda vivamente di specificare un motivo concreto per la richiesta di accesso nella descrizione. Ad esempio, “Per scattare foto del profilo” è meglio di “Per accedere alla fotocamera”. Testi specifici aumentano la fiducia dell'utente e il tasso di concessione. Secondo Localytics (2023), le descrizioni personalizzate aumentano il consenso dal 15 al 25% rispetto a formulazioni generiche.
Non confondere NS*UsageDescription con ATT (App Tracking Transparency). Usage Description è una richiesta di accesso alle risorse di sistema (fotocamera, geolocalizzazione, foto), mentre ATT è una richiesta di tracciamento (accesso a IDFA). ATT utilizza un framework separato AppTrackingTransparency e la chiave NSUserTrackingUsageDescription, che non fa parte di NS*UsageDescription.
Ciò che hanno in comune è che entrambi utilizzano una finestra di dialogo di sistema con testo che l'app non può modificare. La differenza è che Usage Description opera a livello di risorse, mentre ATT opera a livello di identificatore del dispositivo. Le chiavi NS*UsageDescription sono state introdotte in iOS 6, ATT — in iOS 14.5.
Con ogni versione di iOS, Apple ha aggiunto nuove risorse protette e chiavi corrispondenti. iOS 6: contatti, calendario, promemoria, foto. iOS 7: microfono. iOS 8: HomeKit, Salute. iOS 10: libreria multimediale, Siri. iOS 11: NFC. iOS 14: tracciamento (ATT). iOS 17: accesso agli appunti (richiede conferma aggiuntiva).
Importante: se l'app utilizza un'API introdotta in una versione specifica di iOS ma la versione minima supportata è inferiore, la chiave è comunque obbligatoria. iOS verifica la presenza della chiave prima della prima chiamata API, indipendentemente dalla versione su cui l'app è in esecuzione.
L'elenco completo delle chiavi dipende dalle funzionalità utilizzate dall'app. Esaminiamo le 14 chiavi principali più comunemente richieste nelle app mobili.
La chiave NSCameraUsageDescription è obbligatoria quando si accede alla fotocamera tramite AVCaptureDevice o UIImagePickerController con sorgente .camera. La chiave NSMicrophoneUsageDescription è necessaria quando si registra audio tramite AVAudioRecorder o quando si riprende video con audio. Entrambe le chiavi sono spesso necessarie insieme se l'app registra video.
La chiave NSPhotoLibraryUsageDescription viene utilizzata quando si leggono foto e video dalla libreria multimediale dell'utente tramite PHPicker o UIImagePickerController. La chiave NSPhotoLibraryAddUsageDescription viene utilizzata se l'app salva solo foto ma non le legge. La prima richiede accesso in lettura, la seconda — solo accesso in scrittura.
La chiave NSLocationWhenInUseUsageDescription fornisce l'accesso alla geolocalizzazione quando l'app è attiva (a schermo). NSLocationAlwaysAndWhenInUseUsageDescription fornisce accesso sempre (inclusa la modalità in background). iOS richiede entrambe le chiavi se è necessario l'accesso permanente: prima WhenInUse, poi Always.
Le chiavi NSLocationTemporaryUsageDescription e NSLocationPreciseUsageDescription sono chiavi aggiuntive per richiedere accesso temporaneo o geolocalizzazione precisa. La posizione precisa richiede un'autorizzazione separata e l'utente può attivare solo la posizione approssimativa.
| Chiave | Risorsa | Disponibile da iOS |
|---|---|---|
| NSCameraUsageDescription | Fotocamera | 6.0 |
| NSMicrophoneUsageDescription | Microfono | 7.0 |
| NSPhotoLibraryUsageDescription | Libreria multimediale (lettura) | 6.0 |
| NSPhotoLibraryAddUsageDescription | Libreria multimediale (scrittura) | 11.0 |
| NFCReaderUsageDescription | NFC | 11.0 |
La chiave NSContactsUsageDescription fornisce l'accesso ai contatti dell'utente tramite CNContactStore. NSCalendarsUsageDescription fornisce l'accesso al calendario per leggere e creare eventi. NSRemindersUsageDescription fornisce l'accesso ai promemoria. NSBluetoothAlwaysUsageDescription fornisce l'accesso al Bluetooth in background (ad esempio, per dispositivi BLE).
La chiave NSHealthShareUsageDescription fornisce l'accesso in lettura ai dati HealthKit. NSHealthUpdateUsageDescription fornisce l'accesso in scrittura ai dati HealthKit. Entrambe sono obbligatorie se l'app lavora con dati sanitari. Apple esamina attentamente le app che utilizzano HealthKit e può rifiutare l'app se la descrizione dell'uso non corrisponde alla funzionalità.
Il testo in Usage Description deve essere specifico, veritiero e conciso. Apple fornisce raccomandazioni sulla formulazione e i revisori verificano la corrispondenza con la funzionalità.
Una buona descrizione è composta da tre parti: cosa fa esattamente l'app con la risorsa, perché l'utente ne ha bisogno e quale beneficio ottiene l'utente concedendo l'accesso. Esempio: “Per scattare foto del profilo e caricarli sul tuo profilo.” Evita frasi generiche: “Per migliorare le prestazioni dell'app” non spiega perché è necessaria la fotocamera.
Apple vieta descrizioni fuorvianti. Se dice “Per scattare foto” ma l'app registra anche video, ciò può essere considerato ingannevole. Il revisore può rifiutare l'app o richiedere chiarimenti. In iOS 17, Apple ha aggiunto la convalida automatica: la descrizione deve contenere parole chiave corrispondenti alla risorsa richiesta.
Localizzazione: la descrizione deve essere tradotta in tutte le lingue supportate dall'app. Se l'app è disponibile in 10 lingue, ogni chiave Usage Description deve avere traduzioni nei file Localizable.strings o InfoPlist.strings. Apple raccomanda di utilizzare InfoPlist.strings per localizzare le chiavi Info.plist.
Per localizzare Usage Description, non è necessario duplicare Info.plist per ogni lingua. Crea un file InfoPlist.strings in ogni directory della lingua e specifica i valori delle chiavi. iOS utilizzerà automaticamente la lingua corretta nella finestra di dialogo. Xcode supporta la localizzazione di base per Info.plist a partire dalla versione 14.
<!-- InfoPlist.strings (Russian) -->
"NSCameraUsageDescription" =
"Per scansionare codici QR";
"NSPhotoLibraryUsageDescription" =
"Per caricare immagini sul profilo";
"NSLocationWhenInUseUsageDescription" =
"Per mostrare negozi vicini sulla mappa";
L'implementazione corretta di Usage Description include l'aggiunta di chiavi a Info.plist, la verifica dello stato dell'autorizzazione nel codice e la gestione del rifiuto.
In Xcode, apri Info.plist, passa il mouse su una riga e fai clic su “+”. Inserisci il nome della chiave (ad esempio, NSCameraUsageDescription) e specifica la stringa di descrizione. Xcode completa automaticamente i nomi delle chiavi, riducendo il rischio di errori di battitura. Dopo l'aggiunta, ricostruisci il progetto e verifica che la chiave appaia nel binario finale.
Importante: le chiavi sono sensibili a maiuscole/minuscole. NSCameraUsageDescription è corretto, NSCamerausagedescription è un errore. Una chiave errata viene ignorata e l'app si bloccherà quando chiama l'API. Usa la copia dalla documentazione Apple o il completamento automatico di Xcode per evitare errori di battitura.
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)")
}
}
}
Se l'utente rifiuta l'accesso, l'app non deve richiamare la finestra di dialogo di sistema — non è possibile. Mostra invece una schermata informativa che spiega come attivare l'accesso tramite Impostazioni, con un pulsante “Apri Impostazioni” (UIApplicationOpenSettingsURLString). Questa pratica migliora l'esperienza utente e la probabilità che l'utente attivi l'accesso.
Non mostrare un avviso che chiede di attivare l'accesso immediatamente dopo il rifiuto — dai all'utente il tempo di capire perché potrebbe aver bisogno di questa funzionalità. È meglio mostrare la spiegazione quando si tenta di utilizzare la funzionalità che richiede questa autorizzazione. UX Movement (2023) raccomanda di mostrare la schermata di spiegazione 2-3 sessioni dopo il rifiuto.
func showSettingsAlert(for feature: String) {
let alert = UIAlertController(
title: "Accesso a \(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)
}
L'assenza di una chiave Usage Description obbligatoria provoca un arresto immediato dell'app alla prima chiamata dell'API corrispondente. Non è un avviso di Xcode, ma un crash in fase di esecuzione con NSInvalidArgumentException e un messaggio nella console: “Questa app si è bloccata perché ha tentato di accedere a dati sensibili alla privacy senza una descrizione di utilizzo.”
iOS verifica la presenza della chiave NS*UsageDescription in Info.plist alla prima chiamata API per una risorsa protetta. Se la chiave è assente, il sistema operativo termina immediatamente l'app con un segnale SIGABRT. Questo accade anche sui dispositivi di debug — Xcode mostra l'eccezione nel log, ma il debugger non la cattura come punto di interruzione.
Il crash si riproduce su dispositivi reali e simulatore. L'unico modo per evitarlo è aggiungere la chiave prima di chiamare l'API. L'analizzatore statico di Xcode non sempre avvisa della mancanza della chiave, specialmente se l'API viene chiamata tramite SDK di terze parti. I tester di TestFlight vedranno anche il crash, il che può portare a recensioni negative.
Situazione speciale con iOS 17+: Apple ha introdotto un controllo aggiuntivo per l'accesso agli appunti (UIPasteboard). Se l'app legge gli appunti senza un'azione esplicita dell'utente, iOS mostra un banner di avviso, anche se la chiave Usage Description è presente. Gli appunti non richiedono una chiave separata, ma Apple raccomanda di minimizzare la lettura automatica.
Oltre al crash in fase di esecuzione, l'assenza di una chiave può causare il rifiuto dell'app durante la revisione. Apple controlla Info.plist in fase di revisione e può rifiutare la build se rileva chiamate API senza le chiavi corrispondenti. Xcode non blocca l'archiviazione, ma App Store Connect può restituire un errore durante l'elaborazione del binario.
Se l'app non utilizza direttamente la risorsa ma un SDK di terze parti lo fa (ad esempio, un SDK di analisi richiede IDFA), lo sviluppatore deve comunque aggiungere la chiave corrispondente. Apple controlla tutte le chiamate API nel binario, incluso il codice delle librerie statiche e dinamiche. L'errore “Chiave Info.plist mancante” è una delle cause più comuni di rifiuto degli aggiornamenti.
Domande frequenti
Sì, se un SDK di terze parti chiama l'API di accesso alle risorse (fotocamera, geolocalizzazione, foto), la chiave è obbligatoria. iOS controlla l'intero binario, incluse le dipendenze, e blocca l'app se la chiave è assente.
No, ogni risorsa protetta richiede una chiave separata. Ad esempio, NSCameraUsageDescription non sostituisce NSMicrophoneUsageDescription. Il sistema cerca la chiave specifica per nome quando chiama ogni API.
Mostra una schermata che spiega come attivare l'accesso tramite Impostazioni → App e offri un pulsante per aprire le impostazioni dell'app. La finestra di dialogo di sistema non può essere attivata nuovamente a livello di programmazione.
Crea un file InfoPlist.strings per ogni lingua e specifica le traduzioni. iOS utilizza automaticamente la lingua del dispositivo quando mostra la finestra di dialogo. Xcode supporta anche la localizzazione di base per Info.plist.
Il simulatore iOS riproduce completamente il comportamento del dispositivo, inclusi i controlli di Usage Description. Se la chiave è assente, il simulatore terminerà anche l'app con un'eccezione. Questo è un comportamento di debug previsto.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche