مجوز دسترسی به مخاطبین مکانیزمی از سیستمعاملهای موبایل است که قبل از خواندن دفترچه تلفن دستگاه، رضایت صریح کاربر را الزامی میکند. در iOS دسترسی به مخاطبین از طریق CNContactStore و در Android از طریق Contacts API و سیستم runtime permissions انجام میشود. به گفته Apple Developer Documentation, 2025، از iOS 18 همه برنامهها ملزم به استفاده از Contacts Access API یکپارچه هستند. پیادهسازی صحیح درخواست مجوز شانس تأیید توسط ناظران فروشگاههای برنامه را افزایش میدهد.
نکات کلیدی
مجوز دسترسی به مخاطبین مکانیزمی از سیستمعامل است که از دفترچه تلفن کاربر در برابر خواندن غیرمجاز توسط برنامههای شخص ثالث محافظت میکند. در سیستمعاملهای موبایل، مخاطبین دادههای محرمانه محسوب میشوند زیرا شامل نامها، شماره تلفنها، آدرسهای ایمیل و عکسهای افراد اطراف کاربر هستند.
در iOS این مجوز توسط فریمورک Contacts و کلاس CNContactStore تنظیم میشود. کاربر در اولین درخواست دسترسی، یک دیالوگ سیستمی میبیند که میتواند دسترسی را اعطا یا رد کند. در Android حفاظت بر اساس سیستم runtime permissions است: برنامه READ_CONTACTS را در مانیفست مشخص کرده و در زمان اجرا از طریق ActivityResultLauncher یا فرگمنت با پردازش نتیجه درخواست میکند.
بر اساس دادههای Statista (2025)، بیش از 68٪ کاربران iOS و 54٪ کاربران Android در اولین درخواست برنامه از دسترسی به مخاطبین خودداری میکنند. این بدان معناست که توسعهدهنده نه تنها باید درخواست را به درستی پیادهسازی کند، بلکه باید دلیل نیاز به دسترسی را برای کاربر توضیح دهد.
استاندارد صنعتی — درخواست دسترسی فقط در زمانی که عملکرد واقعاً مورد نیاز است، نه در اولین راهاندازی. این رویکرد درصد رد را کاهش داده و تجربه کاربری را بهبود میبخشد.
در اکوسیستم Apple، دسترسی به مخاطبین توسط فریمورک Contacts که در iOS 9 معرفی شد، تنظیم میشود. کلاس CNContactStore روشهایی برای درخواست مجوز و انجام عملیات خواندن و نوشتن ارائه میدهد. در اولین فراخوانی requestAccess(for:) سیستم یک دیالوگ بومی با توضیح دلیل دسترسی نمایش میدهد.
از iOS 17، Apple حالت دسترسی یکبارمصرف (single contact access) را معرفی کرد. کاربر میتواند یک مخاطب را از دفترچه تلفن انتخاب کرده و بدون افشای کل پایگاه داده به برنامه ارسال کند. این حالت از طریق CNContactPickerViewController پیادهسازی میشود و نیازی به فراخوانی requestAccess(for:) ندارد.
توسعهدهنده باید بداند: اگر برنامه دسترسی کامل درخواست کند اما از نظر عملکردی یک مخاطب کافی باشد، ناظران App Store ممکن است بیلد را رد کنند. بر اساس Apple App Review Guidelines (2025)، بخش 5.1.1 صراحتاً حداقل دادههای ضروری را الزامی میکند.
با انتشار iOS 18، Apple الزامات Privacy Manifest — فایل privacy.xcprivacy را سختتر کرد که در آن توسعهدهنده دلیل دسترسی به دادههای محافظتشده را اعلام میکند. برای مخاطبین از کلید NSContactsUsageDescription با متن بومیسازیشدهای که در دیالوگ سیستمی نمایش داده میشود، استفاده میگردد.
بدون privacy manifest صحیح، برنامه از نظارت App Store Connect عبور نمیکند. متن توضیح باید مشخص باشد: نه «برای بهبود عملکرد»، بلکه «برای جستجوی دوستان با شماره تلفن».
در Android دسترسی به مخاطبین با مجوز READ_CONTACTS محافظت میشود که در دسته خطرناک (dangerous) قرار دارد — باید در زمان اجرا درخواست شود، نه فقط هنگام نصب. مکانیزم runtime permissions در Android 6.0 (API 23) معرفی شد و همچنان روش اصلی حفاظت از دادههای محرمانه است.
مجوز READ_CONTACTS در مانیفست از طریق تگ uses-permission مشخص شده و در کد از طریق ActivityResultLauncher یا فرگمنت با onRequestPermissionsResult درخواست میشود. کاربر میتواند درخواست را رد کرده یا گزینه «دیگر نپرس» را انتخاب کند، پس از آن برنامه باید رد را به درستی پردازش کند.
از Android 14 (API 34) رفتار runtime permissions تغییر کرد: با رد دو درخواست متوالی، سیستمعامل به طور خودکار پرچم neverAskAgain را تنظیم میکند. بر اساس Google Developer Documentation (2024)، توسعهدهنده باید قبل از درخواست مجدد وضعیت را از طریق shouldShowRequestPermissionRationale بررسی کند.
برای خواندن مخاطبین، Android از ContentProvider به نام ContactsContract استفاده میکند. این یک پایگاه داده ساختاریافته است که از طریق ContentResolver قابل دسترسی است. دادهها در چندین جدول سازماندهی شدهاند: Contacts (مخاطبین)، RawContacts (رکوردهای خام از حسابهای مختلف)، Data (اطلاعات جزئی: تلفنها، ایمیل، آدرسها).
پرسوجوی ContactsContract از طریق URI ContactsContract.Contacts.CONTENT_URI انجام میشود. توسعهدهنده باید حداقل ستونها را درخواست کرده و از پروجکشن برای فیلتر کردن فیلدها استفاده کند — این کار اجرای پرسوجو را سرعت بخشیده و مصرف حافظه را کاهش میدهد.
پیادهسازی عملی درخواست دسترسی به مخاطبین در iOS و Android متفاوت است. در زیر نمونههای مشخص به زبانهای Swift و Kotlin با پردازش تمام حالتهای ممکن مجوز ارائه شده است.
در iOS درخواست از طریق متد requestAccess کلاس CNContactStore انجام میشود. نتیجه در یک closure با مقدار بولی و خطای اختیاری بازگردانده میشود. مثال زیر چرخه کامل درخواست با پردازش وضعیت را نشان میدهد.
import Contacts
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
if granted {
print("دسترسی به مخاطبین دریافت شد")
// انجام عملیات مخاطبین
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
try? store.enumerateContacts(with: request) { contact, stop in
print("\(contact.givenName) \(contact.familyName)")
}
} else {
print("دسترسی رد شد: \(error?.localizedDescription ?? "خطای ناشناخته")")
}
}
در Android درخواست از طریق ActivityResultLauncher با قرارداد RequestPermission انجام میشود. در مثال زیر کار با ContactsContract.ContentProvider پس از دریافت مجوز نشان داده شده است.
val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
val uri = ContactsContract.Contacts.CONTENT_URI
val cursor = contentResolver.query(uri, null, null, null, null)
cursor?.use {
val nameIndex = it.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
while (it.moveToNext()) {
val name = it.getString(nameIndex)
Log.d("Contacts", "Contact: $name")
}
}
} else {
// توضیح دلیل نیاز به دسترسی به کاربر
showRationaleDialog()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissionLauncher.launch(android.Manifest.permission.READ_CONTACTS)
}
توسعهدهندگان با تجربه برنامههای موبایل از مجموعهای از روشهای اثباتشده هنگام کار با مجوز دسترسی به مخاطبین پیروی میکنند. این قوانین به عبور از نظارت فروشگاههای برنامه و حفظ اعتماد کاربران کمک میکند. پیروی از بهترین روشها فرآیند انتشار و پشتیبانی برنامه را به طور قابل توجهی ساده میکند.
هرگز در اولین راهاندازی برنامه دسترسی به مخاطبین را درخواست نکنید. اولین درخواست باید در زمینه یک عملکرد خاص رخ دهد: جستجوی دوستان، دعوت شرکتکنندگان، وارد کردن مخاطبین. کاربری که دلیل درخواست را میفهمد، طبق تحقیقات Apptentive (2024)، 2-3 برابر بیشتر موافقت میکند.
اگر عملکرد برای دسترسی به یک مخاطب کافی است — از CNContactPickerViewController در iOS یا implicit intent ACTION_PICK در Android استفاده کنید. این روشها به مجوز قبلی نیاز ندارند و به کاربر اجازه میدهند بدون افشای کل دفترچه تلفن به برنامه، رکورد را به طور مستقل انتخاب کند.
برنامه باید وضعیت رد درخواست توسط کاربر را به درستی پردازش کند. در iOS وضعیت را از طریق CNContactStore.authorizationStatus(for:) بررسی کرده و در صورت نیاز کاربر را به تنظیمات هدایت کنید. در Android از shouldShowRequestPermissionRationale برای نمایش توضیح اضافی قبل از درخواست مجدد استفاده کنید.
هرگز بلافاصله پس از رد، دیالوگ تکراری نشان ندهید — این به عنوان پرخاشگری تلقی شده و امتیاز برنامه را کاهش میدهد. بهترین روش: پس از مدتی، صفحهای با توضیح و دکمه «رفتن به تنظیمات» نشان دهید که از طریق Intent صفحه سیستم مجوزها را باز میکند. سناریوی رد را روی دستگاههای واقعی تست کنید — شبیهسازها همیشه رفتار دیالوگهای مجوز سیستمی را به درستی بازتولید نمیکنند.
سؤالات متداول
برنامهها برای عملکردهایی مانند جستجوی دوستان، دعوت شرکتکنندگان، پر کردن خودکار فرمها و همگامسازی با سرور به دسترسی به مخاطبین نیاز دارند. مثالها: پیامرسانها مخاطبین را با شماره تلفن جستجو میکنند، برنامههای CRM مشتریان را وارد میکنند.
دسترسی یکبارمصرف (iOS 17+) از طریق CNContactPickerViewController به کاربر امکان میدهد بدون افشای کل دفترچه تلفن، یک مخاطب را انتخاب کند. دسترسی کامل به برنامه اجازه میدهد تمام مخاطبین دستگاه را از طریق CNContactStore بخواند. دسترسی یکبارمصرف امنتر است و نیازی به مشخص کردن NSContactsUsageDescription در privacy manifest ندارد.
در iOS به تنظیمات — حریم خصوصی و امنیت — مخاطبین رفته و دسترسی را برای برنامه خاص غیرفعال کنید. در Android تنظیمات — برنامهها — برنامه مورد نظر — مجوزها — مخاطبین را باز کرده و «رد» را انتخاب کنید.
Privacy Manifest (فایل privacy.xcprivacy) — سند اجباری برای iOS 18+ که در آن توسعهدهنده دلایل دسترسی به دادههای محافظتشده از جمله مخاطبین را اعلام میکند. کلید NSContactsUsageDescription شامل توضیح بومیسازیشدهای است که در دیالوگ سیستمی درخواست مجوز نمایش داده میشود.
Android READ_CONTACTS را به عنوان مجوز خطرناک (dangerous permission) طبقهبندی میکند زیرا به دادههای شخصی کاربر دسترسی میدهد. مکانیزم runtime permissions که در Android 6.0 معرفی شد، نیاز به رضایت صریح در زمان اجرا دارد، نه فقط هنگام نصب برنامه.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید