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)، توضیحات سفارشی میزان رضایت را ۱۵-۲۵٪ در مقایسه با عبارات کلی افزایش میدهند.
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 بررسی میکند، صرفنظر از نسخهای که برنامه روی آن اجرا میشود.
فهرست کامل کلیدها بستگی به این دارد که برنامه از چه عملکردهایی استفاده میکند. ۱۴ کلید اصلی که اغلب در برنامههای موبایل مورد نیاز هستند را بررسی میکنیم.
کلید 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 — دسترسی به بلوتوث در پسزمینه (مثلاً برای دستگاههای BLE).
کلید NSHealthShareUsageDescription — دسترسی به خواندن دادههای HealthKit. NSHealthUpdateUsageDescription — دسترسی به نوشتن دادهها در HealthKit. اگر برنامه در حوزه سلامت کار میکند، هر دو اجباری هستند. Apple برنامههای استفادهکننده از HealthKit را به دقت بررسی میکند و در صورت عدم تطابق توضیحات با عملکرد، میتواند رد کند.
متن در Usage Description باید مشخص، واقعی و مختصر باشد. Apple توصیههایی برای عبارات ارائه میدهد و بازبینان مطابقت آنها را با عملکرد بررسی میکنند.
توضیحات خوب از سه بخش تشکیل شده است: برنامه دقیقاً با منبع چه میکند، چرا کاربر به این نیاز دارد و چه سودی برای کاربر از اعطای دسترسی دارد. مثال: «برای گرفتن عکس پروفایل و بارگذاری آن در فرم». از عبارات کلی پرهیز کنید: «برای بهبود عملکرد برنامه» توضیح نمیدهد چرا دوربین لازم است.
Apple توضیحات گمراهکننده را ممنوع میکند. اگر نوشته شده «برای گرفتن عکس» اما برنامه همچنین ویدیو ضبط میکند، این میتواند فریبنده تلقی شود. بازبین میتواند برنامه را رد کند یا توضیح بخواهد. در iOS 17 Apple بررسی خودکار اضافه کرد: توضیحات باید شامل کلمات کلیدی مربوط به منبع درخواستشده باشد.
محلیسازی: توضیحات باید به تمام زبانهایی که برنامه پشتیبانی میکند ترجمه شود. اگر برنامه به ۱۰ زبان در دسترس است، هر کلید Usage Description باید ترجمه در فایلهای Localizable.strings یا InfoPlist.strings داشته باشد. Apple توصیه میکند از InfoPlist.strings برای محلیسازی کلیدهای Info.plist استفاده کنید.
برای محلیسازی Usage Description نیازی به تکرار Info.plist برای هر زبان نیست. فایل InfoPlist.strings را در هر دایرکتوری زبانی ایجاد کنید و مقادیر کلیدها را مشخص کنید. iOS به طور خودکار زبان مناسب را در دیالوگ قرار میدهد. Xcode از نسخه ۱۴ محلیسازی پایه را برای Info.plist پشتیبانی میکند.
<!-- 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) توصیه میکند صفحه توضیح را ۲-۳ جلسه پس از رد نشان دهید.
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 حتی اگر کلید Usage Description وجود داشته باشد، بنر هشدار نمایش میدهد. برای کلیپبورد کلید جداگانه لازم نیست، اما Apple به حداقل رساندن خواندن خودکار را توصیه میکند.
علاوه بر کرش زمان اجرا، نبود کلید میتواند دلیلی برای رد برنامه در هنگام بازبینی باشد. Apple Info.plist را در مرحله بازبینی بررسی میکند و اگر فراخوانی API بدون کلیدهای مربوطه پیدا کند، میتواند build را رد کند. 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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید