Το Info.plist Usage Description είναι υποχρεωτικά κλειδιά στο αρχείο Info.plist της εφαρμογής iOS που περιέχουν το κείμενο που εμφανίζεται στον χρήστη όταν ζητείται πρόσβαση σε λειτουργίες συστήματος: κάμερα, μικρόφωνο, γεωτοποθεσία, άλμπουμ φωτογραφιών και άλλα. Κάθε τέτοιο κλειδί έχει το πρόθεμα NS*UsageDescription και παρέχει μια συμβολοσειρά που εξηγεί τον λόγο του αιτήματος πρόσβασης. Σύμφωνα με τον Οδηγό Information Property List της Apple, η απουσία κλειδιού για τον αιτούμενο πόρο οδηγεί σε άμεση κατάρρευση της εφαρμογής.
Κύρια σημεία
Το 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). Αυτή η πρακτική βελτιώνει την εμπειρία χρήστη και αυξάνει την πιθανότητα ο χρήστης να ενεργοποιήσει την πρόσβαση.
Μην εμφανίζετε ειδοποίηση με αίτημα ενεργοποίησης πρόσβασης αμέσως μετά την άρνηση — δώστε στον χρήστη την ευκαιρία να κατανοήσει γιατί μπορεί να χρειαστεί αυτή τη λειτουργία. Είναι καλύτερο να εμφανίσετε εξήγηση κατά την προσπάθεια χρήσης της λειτουργικότητας που απαιτεί τη συγκεκριμένη άδεια. Το 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, αλλά κατάρρευση χρόνου εκτέλεσης με εξαίρεση 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 εμφανίζει banner προειδοποίησης, ακόμη κι αν το κλειδί Usage Description υπάρχει. Για το πρόχειρο δεν απαιτείται ξεχωριστό κλειδί, αλλά η Apple συνιστά ελαχιστοποίηση της αυτόματης ανάγνωσης.
Εκτός από την κατάρρευση χρόνου εκτέλεσης, η απουσία κλειδιού μπορεί να είναι λόγος απόρριψης της εφαρμογής κατά τη διαδικασία ελέγχου. Η Apple ελέγχει το Info.plist στο στάδιο της επιθεώρησης και μπορεί να απορρίψει το build εάν εντοπίσει κλήσεις 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης