PhotoKit هو إطار عمل Apple للعمل مع مكتبة الوسائط على iOS و macOS، يوفر وصولًا مباشرًا إلى الصور والفيديو و Live Photos على الجهاز. وفقًا لوثائق Apple، يستبدل الإطار AssetsLibrary المتقادم ويدعم iCloud والألبومات والتحرير و Change Tracking. PhotoKit يوفر API موحدة للاستعلامات والتخزين المؤقت وتغييرات مكتبة الوسائط مع مماثلة تلقائية عبر iCloud.
النقاط الرئيسية
PhotoKit هو إطار عمل Apple (طرح في iOS 8، macOS 10.11) يوفر API موجهًا نحو الكائنات للعمل مع مكتبة الوسائط النظامية. على عكس AssetsLibrary، يتعامل PhotoKit مع مكتبة الوسائط كقاعدة بيانات: تعيد الاستعلامات كائنات PHAsset و PHCollection و PHCollectionList التي تمثل المحتوى وهيكل التخزين.
يدعم PhotoKit جميع أنواع الوسائط: الصور (JPEG، HEIF، RAW)، الفيديو (MOV، MP4)، Live Photos واللقطات المتتالية. يدير الإطار مماثلة iCloud تلقائيًا: إذا كانت الصورة مخزنة في iCloud، يطلبها PhotoKit عبر الشبكة ويبلغ عن التقدم عبر PHImageRequestOptions.progressHandler.
الميزة الرئيسية لـ PhotoKit هي نموذج البيانات القائم على PHObject مع معرف محلي (localIdentifier) يبقى ثابتًا بين الجلسات. يتيح لك حفظ مراجع لكائنات الوسائط واستعادتها بعد إعادة تشغيل التطبيق دون إعادة الاستعلام.
يتكون PhotoKit من ثلاثة مستويات: نموذج البيانات (PHObject)، الاستعلامات (PHFetchResult) والتغييرات (PHPhotoLibrary.performChanges). نموذج البيانات هرمي: يوجد PHAsset (صورة/فيديو) داخل PHAssetCollection (ألبوم)، وتتجمع الألبومات في PHCollectionList (مجلد).
تتم الاستعلامات عبر PHAsset.fetchAssets و PHAssetCollection.fetchAssetCollections. جميع طرق fetch متزامنة وتعيد PHFetchResult، والذي ينفذ الاستعلام فورًا ضد قاعدة بيانات مكتبة الوسائط. يدعم PHFetchResult الوصول السريع حسب الفهرس (object(at:)) والتعداد عبر enumerateObjects.
PHFetchOptions هو كائن لتكوين الاستعلامات: الترتيب (sortDescriptors)، المسند (predicate)، تضمين الوسائط المخفية والمحذوفة (includeHiddenAssets، includeAllBurstAssets). تسمح خيارات fetch بالتصفية حسب نوع الوسائط: PHAssetMediaType.image، .video، .audio.
يضم PhotoKit مجموعة من الفئات للوصول إلى مكتبة الوسائط والاستعلام عنها وتعديلها. فهم كل منها ضروري للعمل بفعالية مع الإطار.
PHAsset هو كائن غير قابل للتغيير يمثل عنصر وسائط واحد. يحتوي على بيانات وصفية: mediaType، mediaSubtypes، creationDate، location، pixelWidth، pixelHeight، duration (للفيديو)، isFavorite، burstIdentifier. LocalIdentifier هو مفتاح نصي ثابت يمكن الوصول إليه حتى بعد إعادة تشغيل التطبيق.
PHAssetCollection هو مجموعة وسائط: ألبومات النظام (Recents، Favorites، Selfies، Screenshots)، ألبومات المستخدم أو Moments (مجمعة تلقائيًا حسب الوقت والمكان). السمات: localizedTitle، assetCollectionType، assetCollectionSubtype، startDate، endDate.
PHCollectionList هو مجلد يحتوي على ألبومات (PHAssetCollection) أو مجلدات أخرى. يستخدم نادرًا، وذلك أساسًا لعرض التسلسل الهرمي في واجهة المستخدم.
لا يعيد PhotoKit UIImage مباشرة من PHAsset — بل يجب طلب صورة عبر PHImageManager. يضمن ذلك تحميل الصورة مع دعم iCloud والتخزين المؤقت والحجم المطلوب.
| المكون | الغرض | الميزة |
|---|---|---|
| PHImageManager.default() | مدير قياسي للطلبات الفردية | لا يوجد تخزين مؤقت بين الطلبات |
| PHCachingImageManager | مدير مع تحميل مسبق للمجموعات | startCachingImages لتمرير سلس |
| PHImageRequestOptions | إعدادات الطلب: الحجم، الوضع، التسليم | synchronous، deliveryMode، progressHandler |
| PHImageRequestID | معرف الطلب للإلغاء | cancelImageRequest(PHImageRequestID) |
يدعم PHImageManager ثلاثة أوضاع تسليم: opportunistic (نسخة مصغرة أولاً، ثم الكاملة)، highQualityFormat (الجودة الكاملة فقط) و fastFormat (أسرع نسخة متاحة). للمجموعات، استخدم دائمًا PHCachingImageManager مع تحميل مسبق للصور للخلايا المرئية.
يستخدم PhotoKit لإنشاء معارض مخصصة ومحررات وتطبيقات وسائط. لننظر إلى ثلاثة سيناريوهات رئيسية.
PHAsset.fetchAssets مع PHFetchOptions مرتبة حسب تاريخ الإنشاء هي الاستعلام الأساسي لبناء معرض صور مخصص. يدعم PHFetchResult التحميل الكسول والوصول التدفقي.
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(
key: "creationDate",
ascending: .false
)]
options.predicate = NSPredicate(
format: "mediaType == %d",
PHAssetMediaType.image.rawValue
)
let allPhotos = PHAsset.fetchAssets(with: options)
print("تم العثور على \(allPhotos.count) صورة")
allPhotos.enumerateObjects { asset, index, stop in
print("الصورة \(index): \(asset.localIdentifier)")
}
PHFetchResult هو حاوية آمنة للخيوط. الوصول إلى الكائنات حسب الفهرس عبر object(at:) لا يحجب واجهة المستخدم، ولكن طلب صورة عبر PHImageManager يجب أن يتم بشكل غير متزامن.
PHCachingImageManager هو فئة فرعية من PHImageManager مع طرق startCachingImages و stopCachingImages للتحميل المسبق. يستخدم في UICollectionView للتمرير السلس.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// التحميل المسبق للخلايا المرئية
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// طلب الصورة عبر PHImageRequestOptions مع الرجوع إلى iCloud
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("جارٍ التنزيل من iCloud: \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("تم الحصول على الصورة: \(image?.size ?? .zero)")
}
تتم التغييرات في مكتبة الوسائط عبر PHPhotoLibrary.shared().performChanges داخل كتلة changeRequest. تتم تجميع جميع العمليات وتطبيقها بشكل معاملي.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("تمت الإضافة إلى المفضلة")
}
}
يوفر PhotoKit آلية لمراقبة تغييرات مكتبة الوسائط عبر بروتوكول PHPhotoLibraryChangeObserver. عندما تحدث أي تغييرات (إنشاء، حذف، تحرير)، يتم استدعاء طريقة photoLibraryDidChange مع كائن PHChange.
PHChange يحتوي على changeDetails لكل نوع استعلام: PHFetchResultChangeDetails مع removedIndexes، insertedIndexes، changedIndexes. يتيح ذلك تطبيق التغييرات على واجهة المستخدم مع حركة: performBatchUpdates مع move، insert، delete لـ UICollectionView.
class PhotosViewController: UIViewController {
var fetchResult: PHFetchResult>PHAsset>?
override func viewDidLoad() {
super.viewDidLoad()
PHPhotoLibrary.shared().register(self)
}
deinit {
PHPhotoLibrary.shared().unregisterChangeObserver(self)
}
}
extension PhotosViewController: PHPhotoLibraryChangeObserver {
func photoLibraryDidChange(_ changeInstance: PHChange) {
guard let fetchResult,
let details = changeInstance.changeDetails(for: fetchResult)
else { return }
DispatchQueue.main.async {
self.fetchResult = details.fetchResultAfterChanges
// تطبيق التغييرات على collectionView
}
}
}
يدعم PhotoKit تحرير الوسائط عبر آلية PHContentEditingInput و PHContentEditingOutput. تطلب التطبيق editingInput مع البيانات الأصلية، تطبق التغييرات وتحفظ النتيجة عبر editingOutput. يحافظ الإطار تلقائيًا على الأصل، مما يسمح للمستخدمين بترجيع التغييرات عن طريق الإعادة إلى الأصل.
تدعم الصور RAW (DNG، CR2، NEF) عبر PHAssetResourceManager، الذي يوفر الوصول إلى ملف RAW الأصلي. لمعالجة RAW، يوصى باستخدام CoreImage مع مرشح CIRAWFilter، الذي يدعم ضبط درجة الحرارة والتعريض والحدة. يدعم PhotoKit أيضًا إمتدادات المحرر عبر Photo Editing Extension (iOS) — يمكن استدعاء تطبيق من محرر النظام لمعالجة صورة أو فيديو محدد.
PhotoKit هو إطار قوي ولكنه يستهلك الموارد بشكل مكثف. قد يؤدي الاستخدام غير الصحيح إلى تباطؤ عند التمرير واستهلاك مفرط للذاكرة. اتبع هذه التوصيات للحصول على أداء أمثل.
PHLivePhoto يتطلب طلبًا منفصلًا عبر PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). لا تطلب Live Photo للخلايا التي تعرض صورًا فقط — استخدم PHLivePhotoBadge كمؤشر.
الأسئلة الشائعة
PhotoKit هو إطار عمل حديث من Apple للعمل مع مكتبة الوسائط، طرح في iOS 8. على عكس AssetsLibrary المتقادم، يوفر PhotoKit نموذج كائنات PHAsset و PHFetchResult مع بحث سريع ودعم iCloud و Change Tracking لمراقبة التغييرات.
استدع PHPhotoLibrary.requestAuthorization(for: .readWrite) مع معالج استدعاء. بعد الحصول على حالة .authorized، يمكنك تنفيذ استعلامات PHAsset.fetchAssets. يتطلب الوصول للكتابة إذن .readWrite. للقراءة فقط — .addOnly.
استخدم PHImageManager.default().requestImage مع المعلمات: asset، targetSize، contentMode و PHImageRequestOptions. تعيد الطريقة غير المتزامنة PHImageRequestID، مما يسمح بإلغاء الطلب. للمجموعات، استخدم PHCachingImageManager مع التحميل المسبق.
سجل مراقبًا عبر PHPhotoLibrary.shared().register(self) ونفذ بروتوكول PHPhotoLibraryChangeObserver. في طريقة photoLibraryDidChange، استلم PHChange مع changeDetails لكل fetchResult وطبق التغييرات على واجهة المستخدم مع حركة.
في PHImageRequestOptions، ضبط isNetworkAccessAllowed = true و progressHandler لتتبع تقدم تنزيل iCloud. أثناء التمرير السريع، عطل الوصول إلى الشبكة وحمل النسخ المحلية فقط لتجنب تأخير التمرير.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا