Photo Library Permission — مجوزی است که برنامه برای دسترسی به عکسها و ویدیوهای ذخیره شده در دستگاه کاربر به آن نیاز دارد. برای انتخاب تصاویر از گالری، ذخیره فایلهای رسانهای و مدیریت آلبومهای عکس الزامی است. بر اساس Apple Developer Documentation, 2024، از iOS 14 به بعد برنامهها باید دسترسی به کتابخانه محدود را درخواست کنند، نه به همه عکسها به یکباره.
نکات کلیدی
Photo Library Permission — مجوز سیستمی است که دسترسی برنامه به فایلهای رسانهای ذخیره شده در دستگاه را تنظیم میکند. هم خواندن (مشاهده و انتخاب عکس و ویدیو) و هم نوشتن (ذخیره فایلهای جدید در گالری) را پوشش میدهد. پلتفرمهای موبایل کتابخانه رسانه را به عنوان داده محرمانه در نظر میگیرند، زیرا عکسها ممکن است حاوی اطلاعات شخصی و حساس باشند.
در Android 13 (API 33) گوگل مجوز واحد READ_EXTERNAL_STORAGE را به سه مجوز جداگانه تقسیم کرد: READ_MEDIA_IMAGES برای عکسها، READ_MEDIA_VIDEO برای ویدیوها و READ_MEDIA_AUDIO برای صدا. این به کاربر اجازه میدهد فقط به نوع خاصی از فایلهای رسانهای دسترسی دهد. در iOS، از iOS 14 به بعد، PhotoKit به کاربر امکان میدهد عکسهای مشخصی را برای دسترسی انتخاب کند، نه اینکه کل کتابخانه را باز کند.
بر اساس Counterpoint Research (2024)، بیش از 70٪ از برنامههای موبایل در دستهبندی شبکههای اجتماعی، ارتباطات و ویرایشگرهای عکس Photo Library Permission را درخواست میکنند. در عین حال، 32٪ از کاربران در صورتی که متوجه نشوند چرا برنامه به عکسهایشان نیاز دارد، دسترسی به گالری را رد میکنند. اپل و گوگل توصیه میکنند برای انتخاب فایلهای جداگانه بدون درخواست دسترسی کامل از PhotoPicker سیستم استفاده شود.
دسترسی به گالری در Android با عرضه Android 13 به طور قابل توجهی تغییر کرد. به جای یک مجوز READ_EXTERNAL_STORAGE، مجوزهای جزئی برای هر نوع فایل رسانهای ظاهر شد که کنترل بیشتری به کاربر میدهد.
از Android 13 به بعد، برای دسترسی به عکسها از READ_MEDIA_IMAGES و برای ویدیوها از READ_MEDIA_VIDEO استفاده میشود. مجوز READ_EXTERNAL_STORAGE دیگر دسترسی به فایلهای رسانهای را فراهم نمیکند — فقط برای خواندن فایلهای غیررسانهای از حافظه مشترک باقی مانده است. اعلام در مانیفست به این صورت است:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
برای سازگاری معکوس با Android 12 و پایینتر باید READ_EXTERNAL_STORAGE نیز اعلام شود. با این حال، Android 13 در صورت وجود مجوزهای جزئی جدید، این مجوز را به طور خودکار نادیده میگیرد. از ویژگی android:maxSdkVersion="32" در مانیفست برای مجوز قدیمی استفاده کنید تا در نسخههای جدید پنهان شود. این کار از درخواست اضافی در دستگاههای دارای Android 13+ جلوگیری میکند.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
درخواست زمان اجرا برای Photo Library Permission در Android از طریق Activity Result API انجام میشود. مثال درخواست دسترسی به تصاویر:
private val photoPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) {
loadGalleryImages()
} else {
showPermissionDenied()
}
}
fun pickPhoto() {
val permission = if (Build.version.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
Manifest.permission.READ_EXTERNAL_STORAGE
}
if (ContextCompat.checkSelfPermission(this, permission)
== PackageManager.PERMISSION_GRANTED) {
loadGalleryImages()
} else {
photoPermissionLauncher.launch(permission)
}
}
دسترسی به گالری در iOS از طریق فریمورک PhotoKit و کلیدهای NSPhotoLibraryUsageDescription و NSPhotoLibraryAddUsageDescription در Info.plist مدیریت میشود. از iOS 14 به بعد، کاربر میتواند فقط به عکسهای انتخاب شده دسترسی دهد (Limited Photo Library).
برای خواندن عکسها از کتابخانه، NSPhotoLibraryUsageDescription و برای نوشتن (ذخیره عکسها)، NSPhotoLibraryAddUsageDescription لازم است. اگر برنامه فقط رسانه ذخیره میکند اما آنها را نمیخواند، کلید دوم کافی است.
<key>NSPhotoLibraryUsageDescription</key>
<string>برنامه برای انتخاب تصویر نمایه و انتشار عکسها به دسترسی به عکسها نیاز دارد.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>برنامه برای ذخیره عکسهای پردازش شده در گالری شما به دسترسی نیاز دارد.</string>
درخواست دسترسی به عکسها در iOS از طریق PHPhotoLibrary.requestAuthorization انجام میشود. از iOS 14 به بعد، وضعیت .limited نشان میدهد که کاربر دسترسی به مجموعه محدودی از عکسها را داده است.
import PhotosUI
func requestPhotoLibraryAccess() {
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async {
switch status {
case .authorized:
self.loadPhotoLibrary()
case .limited:
self.loadSelectedPhotos()
case .denied, .restricted:
self.showSettingsAlert()
case .notDetermined:
break
}
}
}
}
private func loadPhotoLibrary() {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
// کار با نتایج درخواست
}
وضعیت .limited در iOS 14+ به این معنی است که کاربر فقط به چند عکس انتخاب شده دسترسی داده است. برنامه میتواند از طریق دیالوگ سیستمی با فراخوانی PHPhotoLibrary.shared().presentLimitedLibraryPicker درخواست گسترش دسترسی دهد. توصیه میشود این دیالوگ را فقط زمانی نشان دهید که کاربر صریحاً عملکردی را درخواست کند که به عکسهای اضافی نیاز دارد.
PhotoPicker — یک کامپوننت سیستم برای انتخاب فایلهای رسانهای است که نیازی به مجوز دسترسی به کل کتابخانه ندارد. از Android 13 و iOS 14 به بعد، گوگل و اپل توصیه میکنند به جای درخواست Photo Library Permission از PhotoPicker استفاده شود، اگر برنامه فقط نیاز به انتخاب یک یا چند عکس دارد.
در Android 13+، PhotoPicker داخلی (ActivityResultContracts.PickVisualMedia) به کاربر اجازه میدهد بدون ارائه دسترسی به کل گالری، عکس یا ویدیو انتخاب کند. برنامه فقط URI فایلهای انتخاب شده را دریافت میکند. PhotoPicker بدون اعلام هیچ مجوزی در مانیفست کار میکند.
private val pickMedia =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// URI فایل انتخاب شده، بدون دسترسی به کل کتابخانه
showImage(uri)
}
}
fun selectPhoto() {
pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
در iOS 14+، PHPickerViewController معرفی شد — یک picker سیستم که همچنین نیازی به دسترسی به کل کتابخانه ندارد. PHPicker در یک فرآیند جداگانه کار میکند و به کتابخانه برنامه دسترسی ندارد. این روش ترجیحی برای انتخاب عکس در بیشتر سناریوها است.
import PhotosUI
func presentPhotoPicker() {
var config = PHPickerConfiguration()
config.selectionLimit = 1
config.filter = .images
let picker = PHPickerViewController(configuration: config)
picker.delegate = self
present(picker, animated: true)
}
PhotoPicker مناسب نیست اگر برنامه برای عملیات انبوه نیاز به دسترسی به کل کتابخانه دارد: پشتیبانگیری، همگامسازی با ابر، برنامه گالری، مدیر فایل. در این موارد باید Photo Library Permission را درخواست کرده و مورد دسترسی محدود (Limited) را مدیریت کنید. برای iOS، مدیریت وضعیت .limited و پیشنهاد گسترش دسترسی به کاربر الزامی است.
بهترین روشها برای کار با Photo Library Permission به کاهش تعداد ردها و مطابقت با الزامات حریم خصوصی پلتفرمها کمک میکند.
برای انتخاب یک یا چند عکس از PhotoPicker یا PHPicker سیستم استفاده کنید. این کامپوننتها نیازی به مجوز ندارند و بهترین تجربه کاربری را فراهم میکنند. مجوز کامل دسترسی به گالری را فقط در صورتی درخواست کنید که عملکرد برنامه نیاز به دسترسی به کل کتابخانه رسانه دارد. گوگل و اپل به صراحت این رویکرد را در مستندات توسعهدهندگان توصیه میکنند.
اگر برنامه واقعاً به دسترسی کامل به گالری نیاز دارد، یک صفحه مقدماتی با توضیح نشان دهید. توضیح دهید که چرا همه عکسها لازم هستند، نه فقط یکی. به عنوان مثال، یک برنامه پشتیبانگیری باید توضیح دهد که برای ایجاد یک کپی، تمام فایلهای رسانهای را اسکن میکند. Pre-permission screen به دلیل مکانیزم Limited Access در iOS بسیار مهم است.
اگر برنامه فقط عکسها را ذخیره میکند اما آنها را نمیخواند (مثلاً ویرایشگر عکس که نتیجه را ذخیره میکند)، فقط مجوز نوشتن در گالری را درخواست کنید. در Android این WRITE_EXTERNAL_STORAGE (برای Android 12 و پایینتر) یا MediaStore API بدون مجوز (برای Android 10+) است. در iOS از NSPhotoLibraryAddUsageDescription بدون NSPhotoLibraryUsageDescription استفاده کنید.
سوالات متداول
از Android 10 (API 29) به بعد، ذخیره عکس از طریق MediaStore نیازی به مجوز WRITE_EXTERNAL_STORAGE ندارد. سیستم دسترسی به حافظه مشترک برای نوشتن بدون مجوز صریح فراهم میکند. برای خواندن فایلهای دیگران همچنان مجوز مربوطه لازم است.
READ_EXTERNAL_STORAGE — مجوز قدیمی برای خواندن همه فایلها از حافظه مشترک (تا Android 12). READ_MEDIA_IMAGES — مجوز جزئی جدید برای خواندن فقط تصاویر (Android 13+). کاربر میتواند فقط به عکسها دسترسی دهد و دسترسی به ویدیو و صدا را رد کند.
وضعیت .limited به این معنی است که کاربر چند عکس را برای دسترسی انتخاب کرده است. برنامه میتواند دیالوگ سیستم گسترش را از طریق PHPhotoLibrary.shared().presentLimitedLibraryPicker نمایش دهد. توصیه میشود این دیالوگ را فقط به درخواست صریح کاربر نمایش دهید، مثلاً هنگام کلیک روی دکمه «افزودن عکس بیشتر».
بله، با داشتن Photo Library Permission برنامه میتواند دادههای EXIF شامل ژئوتگها، تاریخ عکسبرداری و مدل دوربین را بخواند. در iOS برای دسترسی به ژئوتگها ممکن است به Location Permission اضافی نیاز باشد، زیرا اپل مختصات GPS را داده محرمانه میداند.
از picker سیستم استفاده کنید: PHPicker با filter = .videos در iOS، PickVisualMedia با VideoOnly در Android. در Android برای انتخاب ویدیو از گالری میتوان از Intent(Intent.ACTION_PICK) با MediaStore.Video.Media.EXTERNAL_CONTENT_URI نیز استفاده کرد، اما این نیاز به مجوز READ_EXTERNAL_STORAGE در نسخههای پایینتر از Android 13 دارد.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید