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 підтримує lazy-loading та потоковий доступ.

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 — потокобезпечний контейнер. Доступ до об'єктів за індексом через 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) з обробкою в колбеку. Після отримання статусу .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 виконує синхронний запит до сховища та надає потокобезпечний доступ до результатів.
  • PHCachingImageManager з попереднім завантаженням забезпечує плавний скрол в колекціях без затримок.
  • Change Tracking через PHPhotoLibraryChangeObserver дозволяє UI миттєво реагувати на зміни медіатеки.
  • Синхронізація iCloud вбудована в фреймворк: запит зображення автоматично завантажує його з iCloud з прогресом.
  • Оптимізація — правильний targetSize, скасування запитів та обмеження iCloud при скролі критичні для продуктивності.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також