PhotoKit — какво е това, ключови понятия и PHAsset

Автор: IT Sectr Публикувано: 2026-05-06 Време за четене: 8 мин

PhotoKit — е рамката на Apple за работа с медиатеката на iOS и macOS, предоставяща директен достъп до снимки, видеоклипове и Live Photos на устройството. Според документацията на Apple, рамката заменя остарялата AssetsLibrary и поддържа iCloud, албуми, редактиране и Change Tracking. PhotoKit осигурява единен API за заявки, кеширане и промени в медиатеката с автоматична синхронизация чрез iCloud.

Основни точки

  • PhotoKit — рамка на Apple за работа със системната медиатека, предоставяща достъп до снимки, видеоклипове, Live Photos и албуми.
  • PHAsset — модел на данни, представляващ единично медийно съдържание (снимка или видео) с метаданни: дата, местоположение, тип.
  • PHFetchResult — контейнер за резултати от заявка с поточно зареждане и известия за промени чрез PHPhotoLibraryChangeObserver.
  • PHImageManager — мениджър за получаване на изображения с опции за размер, режим и кеширане чрез PHCachingImageManager.
  • PHPhotoLibrary — входна точка за извършване на промени: създаване, изтриване и редактиране на медийни обекти.

Какво е PhotoKit?

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: модел на данни и заявки

PhotoKit е изграден на три нива: модел на данни (PHObject), заявки (PHFetchResult) и промени (PHPhotoLibrary.performChanges). Моделът на данни е йерархичен: PHAsset (снимка/видео) се намира вътре в PHAssetCollection (албум), албумите се групират в PHCollectionList (папка).

Изпълнение на заявки

Заявките се изпълняват чрез PHAsset.fetchAssets и PHAssetCollection.fetchAssetCollections. Всички fetch методи са синхронни и връщат PHFetchResult, чийто обект незабавно изпълнява заявката към базата данни на медиатеката. PHFetchResult поддържа бърз достъп по индекс (object(at:)) и изброяване чрез enumerateObjects.

  • fetchAssets(with:options:) — заявка на всички медии с филтриране по тип, дата, албум
  • fetchAssetCollections(with:subtype:options:) — заявка на албуми и папки
  • fetchAssets(in:options:) — заявка на медии вътре в конкретен албум

PHFetchOptions

PHFetchOptions — обект за конфигурация на заявката: сортиране (sortDescriptors), предикат (predicate), включване на скрити и изтрити медии (includeHiddenAssets, includeAllBurstAssets). Fetch опциите позволяват филтриране по тип медия: PHAssetMediaType.image, .video, .audio.

Основните класове на PhotoKit

PhotoKit включва набор от класове за достъп, заявки и промяна на медиатеката. Разбирането на всеки от тях е необходимо за ефективна работа с рамката.

PHAsset

PHAsset — неизменим обект, представляващ единично медийно съдържание. Съдържа метаданни: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (за видео), isFavorite, burstIdentifier. LocalIdentifier — стабилен текстов ключ, достъпен дори след рестартиране на приложението.

PHAssetCollection

PHAssetCollection — група медии: системни албуми (Recents, Favorites, Selfies, Screenshots), потребителски албуми или Moments (автоматично групирани по време и място). Атрибути: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.

PHCollectionList

PHCollectionList — папка, съдържаща албуми (PHAssetCollection) или други папки. Използва се рядко, основно за показване на йерархия в потребителския интерфейс.

PHImageManager и кеширане

PhotoKit не връща UIImage директно от PHAsset — трябва да заявите изображението чрез PHImageManager. Това гарантира, че изображението се зарежда, като се вземат предвид iCloud, кеширането и необходимия размер.

КомпонентПредназначениеХарактеристика
PHImageManager.default()Стандартен мениджър за единични заявкиБез кеширане между заявки
PHCachingImageManagerМениджър с предварително зареждане за колекцииstartCachingImages за плавно скролване
PHImageRequestOptionsНастройки на заявка: размер, режим, доставкаsynchronous, deliveryMode, progressHandler
PHImageRequestIDИдентификатор на заявка за отмянаcancelImageRequest(PHImageRequestID)

PHImageManager поддържа три режима на доставка: opportunistic (първо намалена версия, след това пълна), highQualityFormat (само пълно качество) и fastFormat (най-бързата налична версия). За колекции винаги използвайте PHCachingImageManager с предварително зареждане на изображения за видимите клетки.

Примери за използване на PhotoKit в Swift

PhotoKit се използва за създаване на персонализирани галерии, редактори и приложения за работа с медии. Нека разгледаме три ключови сценария.

Заявка на всички снимки от медиатеката

PHAsset.fetchAssets с PHFetchOptions и сортиране по дата на създаване — основна заявка за изграждане на персонализирана фотогалерия. PHFetchResult поддържа мързеливо зареждане и поточен достъп.

swift
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 — thread-safe контейнер. Достъпът до обекти по индекс чрез object(at:) не блокира UI, но заявката за изображение чрез PHImageManager трябва да се изпълни асинхронно.

Зареждане на изображение с кеширане

PHCachingImageManager — подклас на PHImageManager с методи startCachingImages и stopCachingImages за предварително зареждане. Използва се в UICollectionView за плавно скролване.

swift
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)

// Предварително зареждане за видими клетки
cachingManager.startCachingImages(
    for: visibleAssets,
    targetSize: targetSize,
    contentMode: .aspectFill,
    options: nil
)

// Заявка за изображение чрез PHImageRequestOptions с iCloud fallback
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. Всички операции се групират и прилагат транзакционно.

swift
PHPhotoLibrary.shared().performChanges {
    let changeRequest = PHAssetChangeRequest(for: asset)
    changeRequest.isFavorite = .true
} completionHandler: { success, error in
    if success {
        print("Добавено към любими")
    }
}

Промени и наблюдение чрез Change Tracking

PhotoKit предоставя механизъм за наблюдение на промените в медиатеката чрез протокола PHPhotoLibraryChangeObserver. При всяка промяна (създаване, изтриване, редактиране) се извиква методът photoLibraryDidChange с обект PHChange.

PHChange съдържа changeDetails за всеки тип заявка: PHFetchResultChangeDetails с removedIndexes, insertedIndexes, changedIndexes. Това позволява прилагане на промените в UI с анимация: performBatchUpdates с move, insert, delete за UICollectionView.

swift
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
        }
    }
}

Редактиране на RAW и разширения

PhotoKit поддържа редактиране на медии чрез механизма PHContentEditingInput и PHContentEditingOutput. Приложението заявява editingInput с оригинални данни, прилага промени и запазва резултата чрез editingOutput. Рамката автоматично запазва оригинала, позволявайки на потребителя да отмени промените чрез нулиране до оригинала.

RAW снимките (DNG, CR2, NEF) се поддържат чрез PHAssetResourceManager, който предоставя достъп до оригиналния RAW файл. За обработка на RAW се препоръчва използването на CoreImage с филтъра CIRAWFilter, който поддържа настройка на температура, експозиция и рязкост. PhotoKit поддържа също разширения на редактори чрез Photo Editing Extension (iOS) — приложението може да бъде извикано от системния редактор за обработка на избраната снимка или видео.

Оптимизиране на работата с PhotoKit

PhotoKit — мощна, но ресурсоемка рамка. Неправилната употреба може да доведе до забавяне при скролване и прекомерна консумация на памет. Следвайте препоръките за оптимална производителност.

  • Използвайте PHCachingImageManager за колекции — предварителното зареждане на изображения за видимите +-1 екран клетки елиминира закъсненията при скролване
  • Задайте targetSize — никога не изисквайте PHImageManagerMaximumSize за миниатюри. Използвайте размер, равен на физическия размер на клетката, умножен по scale на екрана
  • Отменяйте заявки при повторно използване на клетка — запазете PHImageRequestID и извикайте cancelImageRequest в prepareForReuse
  • Ограничете iCloud заявките — при бързо скролване задайте isNetworkAccessAllowed = false и зареждайте iCloud снимки само при спиране
  • Кеширайте PHFetchResult — повторните fetchAssets със същите опции връщат нов PHFetchResult. Съхранявайте резултата в свойство и актуализирайте чрез Change Observer

PHLivePhoto — изисква отделна заявка чрез PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Не изисквайте Live Photo за клетки, където се показва само снимка — използвайте PHLivePhotoBadge за индикация.

Често задавани въпроси

Какво е PhotoKit и с какво се различава от AssetsLibrary?

PhotoKit — модерна рамка на Apple за работа с медиатеката, представена в iOS 8. За разлика от остарялата AssetsLibrary, PhotoKit предоставя обектен модел PHAsset, PHFetchResult с бързо търсене, поддръжка на iCloud и Change Tracking за наблюдение на промени.

Как да поискам достъп до медиатеката чрез PhotoKit?

Извикайте PHPhotoLibrary.requestAuthorization(for: .readWrite) с обработка в callback. След получаване на статус .authorized можете да изпълнявате заявки PHAsset.fetchAssets. За запис е необходим достъп .readWrite. Само за четене — .addOnly.

Как да получа изображение от PHAsset?

Използвайте PHImageManager.default().requestImage с параметри: asset, targetSize, contentMode и PHImageRequestOptions. Асинхронният метод връща PHImageRequestID, позволяващ отмяна на заявката. За колекции използвайте PHCachingImageManager с предварително зареждане.

Как да проследя промените в медиатеката?

Регистрирайте наблюдател чрез PHPhotoLibrary.shared().register(self) и имплементирайте протокола PHPhotoLibraryChangeObserver. В метода photoLibraryDidChange ще получите PHChange с changeDetails за всеки fetchResult и приложете промените в UI с анимация.

Как да обработвам iCloud снимки в PhotoKit?

В PHImageRequestOptions задайте isNetworkAccessAllowed = true и progressHandler за проследяване на зареждане от iCloud. При бързо скролване изключете мрежовия достъп и зареждайте само локални версии, за да избегнете закъснения при скролване.

Резюме

  • PhotoKit — рамка на Apple за работа с медиатеката, която замени AssetsLibrary от iOS 8 и macOS 10.11.
  • PHAsset — основният модел на данни с локален идентификатор, тип, дата, местоположение и размер.
  • PHFetchResult изпълнява синхронна заявка към хранилището и предоставя thread-safe достъп до резултатите.
  • PHCachingImageManager с предварително зареждане осигурява плавно скролване в колекции без закъснения.
  • Change Tracking чрез PHPhotoLibraryChangeObserver позволява на UI незабавно да реагира на промени в медиатеката.
  • iCloud синхронизация е вградена в рамката: заявката за изображение автоматично го зарежда от iCloud с напредък.
  • Оптимизация — правилен targetSize, отмяна на заявки и ограничение на iCloud при скролване са критични за производителността.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също