PhotoKit — co to jest, kluczowe pojęcia i PHAsset

Autor: IT Sectr Opublikowano: 2026-05-06 Czas czytania: 8 min

PhotoKit — to framework Apple do pracy z biblioteką multimediów na iOS i macOS, zapewniający bezpośredni dostęp do zdjęć, filmów i Live Photos na urządzeniu. Według dokumentacji Apple, framework zastępuje przestarzały AssetsLibrary i obsługuje iCloud, albumy, edycję oraz Change Tracking. PhotoKit zapewnia jednolity API do zapytań, buforowania i zmian w bibliotece multimediów z automatyczną synchronizacją przez iCloud.

Najważniejsze

  • PhotoKit — framework Apple do pracy z systemową biblioteką multimediów, zapewniający dostęp do zdjęć, filmów, Live Photos i albumów.
  • PHAsset — model danych reprezentujący pojedyncze medium (zdjęcie lub wideo) z metadanymi: data, lokalizacja, typ.
  • PHFetchResult — kontener wyników zapytania z ładowaniem strumieniowym i powiadomieniami o zmianach przez PHPhotoLibraryChangeObserver.
  • PHImageManager — menedżer do pobierania obrazów z opcjami rozmiaru, trybu i buforowania przez PHCachingImageManager.
  • PHPhotoLibrary — punkt wejścia do wykonywania zmian: tworzenie, usuwanie i edycja obiektów multimedialnych.

Co to jest PhotoKit?

PhotoKit — framework Apple (wprowadzony w iOS 8, macOS 10.11), zapewniający zorientowany obiektowo API do pracy z systemową biblioteką multimediów. W przeciwieństwie do AssetsLibrary, PhotoKit traktuje bibliotekę multimediów jak bazę danych: zapytania zwracają obiekty PHAsset, PHCollection, PHCollectionList, reprezentujące zawartość i strukturę przechowywania.

PhotoKit obsługuje wszystkie typy multimediów: zdjęcia (JPEG, HEIF, RAW), wideo (MOV, MP4), Live Photos i zdjęcia seryjne. Framework automatycznie zarządza synchronizacją iCloud: jeśli obraz jest przechowywany w iCloud, PhotoKit pobiera go przez sieć i raportuje postęp przez PHImageRequestOptions.progressHandler.

Kluczową cechą PhotoKit jest model danych oparty na PHObject z lokalnym identyfikatorem (localIdentifier), który pozostaje stabilny między sesjami. Umożliwia to zapisywanie odniesień do obiektów multimedialnych i przywracanie ich po ponownym uruchomieniu aplikacji bez ponownego zapytania.

Jak działa PhotoKit: model danych i zapytania

PhotoKit jest zbudowany na trzech poziomach: modelu danych (PHObject), zapytań (PHFetchResult) i zmian (PHPhotoLibrary.performChanges). Model danych jest hierarchiczny: PHAsset (zdjęcie/wideo) znajduje się wewnątrz PHAssetCollection (album), albumy są grupowane w PHCollectionList (folder).

Wykonywanie zapytań

Zapytania są wykonywane przez PHAsset.fetchAssets i PHAssetCollection.fetchAssetCollections. Wszystkie metody fetch są synchroniczne i zwracają PHFetchResult, którego obiekt natychmiast wykonuje zapytanie do bazy danych biblioteki multimediów. PHFetchResult obsługuje szybki dostęp po indeksie (object(at:)) i wyliczanie przez enumerateObjects.

  • fetchAssets(with:options:) — zapytanie wszystkich multimediów z filtrowaniem po typie, dacie, albumie
  • fetchAssetCollections(with:subtype:options:) — zapytanie albumów i folderów
  • fetchAssets(in:options:) — zapytanie multimediów wewnątrz konkretnego albumu

PHFetchOptions

PHFetchOptions — obiekt do konfiguracji zapytania: sortowanie (sortDescriptors), predykat (predicate), uwzględnianie ukrytych i usuniętych multimediów (includeHiddenAssets, includeAllBurstAssets). Opcje fetch pozwalają filtrować po typie medium: PHAssetMediaType.image, .video, .audio.

Główne klasy PhotoKit

PhotoKit zawiera zestaw klas do dostępu, zapytań i zmiany biblioteki multimediów. Zrozumienie każdej z nich jest niezbędne do efektywnej pracy z frameworkiem.

PHAsset

PHAsset — niezmienny obiekt reprezentujący pojedyncze medium. Zawiera metadane: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (dla wideo), isFavorite, burstIdentifier. LocalIdentifier — stabilny klucz tekstowy, dostępny nawet po ponownym uruchomieniu aplikacji.

PHAssetCollection

PHAssetCollection — grupa multimediów: albumy systemowe (Recents, Favorites, Selfies, Screenshots), albumy użytkownika lub Moments (automatycznie grupowane według czasu i miejsca). Atrybuty: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.

PHCollectionList

PHCollectionList — folder zawierający albumy (PHAssetCollection) lub inne foldery. Używany rzadko, głównie do wyświetlania hierarchii w interfejsie użytkownika.

PHImageManager i buforowanie

PhotoKit nie zwraca UIImage bezpośrednio z PHAsset — trzeba pobrać obraz przez PHImageManager. Gwarantuje to, że obraz jest ładowany z uwzględnieniem iCloud, buforowania i wymaganego rozmiaru.

KomponentPrzeznaczenieCecha
PHImageManager.default()Standardowy menedżer do pojedynczych zapytańBrak buforowania między zapytaniami
PHCachingImageManagerMenedżer z preładowaniem dla kolekcjistartCachingImages dla płynnego przewijania
PHImageRequestOptionsUstawienia zapytania: rozmiar, tryb, dostawasynchronous, deliveryMode, progressHandler
PHImageRequestIDIdentyfikator zapytania do anulowaniacancelImageRequest(PHImageRequestID)

PHImageManager obsługuje trzy tryby dostawy: opportunistic (najpierw zmniejszona wersja, potem pełna), highQualityFormat (tylko pełna jakość) i fastFormat (najszybsza dostępna wersja). Dla kolekcji zawsze używaj PHCachingImageManager z preładowaniem obrazów dla widocznych komórek.

Przykłady użycia PhotoKit w Swift

PhotoKit jest używany do tworzenia niestandardowych galerii, edytorów i aplikacji do pracy z multimediami. Rozważmy trzy kluczowe scenariusze.

Pobranie wszystkich zdjęć z biblioteki multimediów

PHAsset.fetchAssets z PHFetchOptions i sortowaniem według daty utworzenia — podstawowe zapytanie do budowania niestandardowej galerii zdjęć. PHFetchResult obsługuje lazy-loading i dostęp strumieniowy.

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("Znaleziono \(allPhotos.count) zdjęć")

allPhotos.enumerateObjects { asset, index, stop in
    print("Zdjęcie \(index): \(asset.localIdentifier)")
}

PHFetchResult — bezpieczny wątkowo kontener. Dostęp do obiektów po indeksie przez object(at:) nie blokuje UI, ale pobranie obrazu przez PHImageManager musi być wykonane asynchronicznie.

Ładowanie obrazu z buforowaniem

PHCachingImageManager — podklasa PHImageManager z metodami startCachingImages i stopCachingImages do preładowania. Używany w UICollectionView do płynnego przewijania.

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

// Preładowanie dla widocznych komórek
cachingManager.startCachingImages(
    for: visibleAssets,
    targetSize: targetSize,
    contentMode: .aspectFill,
    options: nil
)

// Pobranie obrazu przez PHImageRequestOptions z iCloud fallback
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
    DispatchQueue.main.async {
        print("Pobieranie z iCloud: \(progress * 100)%")
    }
}

let requestID = cachingManager.requestImage(
    for: asset,
    targetSize: targetSize,
    contentMode: .aspectFill,
    options: requestOptions
) { image, info in
    print("Otrzymano obraz: \(image?.size ?? .zero)")
}

Edycja biblioteki multimediów: dodawanie do ulubionych

Zmiany w bibliotece multimediów są wykonywane przez PHPhotoLibrary.shared().performChanges wewnątrz bloku changeRequest. Wszystkie operacje są grupowane i stosowane transakcyjnie.

swift
PHPhotoLibrary.shared().performChanges {
    let changeRequest = PHAssetChangeRequest(for: asset)
    changeRequest.isFavorite = .true
} completionHandler: { success, error in
    if success {
        print("Dodano do ulubionych")
    }
}

Zmiany i obserwacja przez Change Tracking

PhotoKit zapewnia mechanizm obserwacji zmian w bibliotece multimediów przez protokół PHPhotoLibraryChangeObserver. Przy każdej zmianie (tworzenie, usuwanie, edycja) wywoływana jest metoda photoLibraryDidChange z obiektem PHChange.

PHChange zawiera changeDetails dla każdego typu zapytania: PHFetchResultChangeDetails z removedIndexes, insertedIndexes, changedIndexes. Umożliwia to zastosowanie zmian w UI z animacją: performBatchUpdates z move, insert, delete dla 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
            // Zastosuj zmiany do collectionView
        }
    }
}

Edycja RAW i rozszerzenia

PhotoKit obsługuje edycję multimediów przez mechanizm PHContentEditingInput i PHContentEditingOutput. Aplikacja żąda editingInput z oryginalnymi danymi, stosuje zmiany i zapisuje wynik przez editingOutput. Framework automatycznie zachowuje oryginał, umożliwiając użytkownikowi przywrócenie zmian przez reset do oryginału.

Zdjęcia RAW (DNG, CR2, NEF) są obsługiwane przez PHAssetResourceManager, który zapewnia dostęp do oryginalnego pliku RAW. Do przetwarzania RAW zaleca się użycie CoreImage z filtrem CIRAWFilter, który obsługuje regulację temperatury, ekspozycji i ostrości. PhotoKit obsługuje również rozszerzenia edytorów przez Photo Editing Extension (iOS) — aplikacja może być wywołana z systemowego edytora do przetwarzania wybranego zdjęcia lub filmu.

Optymalizacja pracy z PhotoKit

PhotoKit — potężny, ale zasobożerny framework. Niewłaściwe użycie może prowadzić do spowolnień podczas przewijania i nadmiernego zużycia pamięci. Postępuj zgodnie z zaleceniami dla optymalnej wydajności.

  • Używaj PHCachingImageManager dla kolekcji — preładowanie obrazów dla widocznych +-1 ekran komórek eliminuje opóźnienia podczas przewijania
  • Ustawiaj targetSize — nigdy nie żądaj PHImageManagerMaximumSize dla miniatur. Używaj rozmiaru równego fizycznemu rozmiarowi komórki pomnożonemu przez scale ekranu
  • Anuluj zapytania przy ponownym użyciu komórki — zapisuj PHImageRequestID i wywołuj cancelImageRequest w prepareForReuse
  • Ograniczaj zapytania iCloud — przy szybkim przewijaniu ustaw isNetworkAccessAllowed = false i ładuj zdjęcia z iCloud tylko po zatrzymaniu
  • Buforuj PHFetchResult — ponowne fetchAssets z tymi samymi opcjami zwraca nowy PHFetchResult. Zachowuj wynik we właściwości i aktualizuj przez Change Observer

PHLivePhoto — wymaga osobnego zapytania przez PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Nie żądaj Live Photo dla komórek, gdzie wyświetlane jest tylko zdjęcie — używaj PHLivePhotoBadge do oznaczenia.

Często zadawane pytania

Co to jest PhotoKit i czym różni się od AssetsLibrary?

PhotoKit — nowoczesny framework Apple do pracy z biblioteką multimediów, wprowadzony w iOS 8. W przeciwieństwie do przestarzałego AssetsLibrary, PhotoKit zapewnia model obiektowy PHAsset, PHFetchResult z szybkim wyszukiwaniem, obsługę iCloud oraz Change Tracking do obserwacji zmian.

Jak poprosić o dostęp do biblioteki multimediów przez PhotoKit?

Wywołaj PHPhotoLibrary.requestAuthorization(for: .readWrite) z obsługą w callbacku. Po uzyskaniu statusu .authorized można wykonywać zapytania PHAsset.fetchAssets. Do zapisu wymagany jest dostęp .readWrite. Tylko do odczytu — .addOnly.

Jak uzyskać obraz z PHAsset?

Użyj PHImageManager.default().requestImage z parametrami: asset, targetSize, contentMode i PHImageRequestOptions. Asynchroniczna metoda zwraca PHImageRequestID, umożliwiający anulowanie zapytania. Dla kolekcji używaj PHCachingImageManager z preładowaniem.

Jak śledzić zmiany w bibliotece multimediów?

Zarejestruj obserwatora przez PHPhotoLibrary.shared().register(self) i zaimplementuj protokół PHPhotoLibraryChangeObserver. W metodzie photoLibraryDidChange otrzymasz PHChange z changeDetails dla każdego fetchResult i zastosuj zmiany w UI z animacją.

Jak obsługiwać zdjęcia iCloud w PhotoKit?

W PHImageRequestOptions ustaw isNetworkAccessAllowed = true i progressHandler do śledzenia pobierania z iCloud. Przy szybkim przewijaniu wyłączaj dostęp sieciowy i ładuj tylko lokalne wersje, aby uniknąć opóźnień podczas przewijania.

Podsumowanie

  • PhotoKit — framework Apple do pracy z biblioteką multimediów, który zastąpił AssetsLibrary od iOS 8 i macOS 10.11.
  • PHAsset — podstawowy model danych z lokalnym identyfikatorem, typem, datą, lokalizacją i rozmiarem.
  • PHFetchResult wykonuje synchroniczne zapytanie do magazynu i zapewnia bezpieczny wątkowo dostęp do wyników.
  • PHCachingImageManager z preładowaniem zapewnia płynne przewijanie w kolekcjach bez opóźnień.
  • Change Tracking przez PHPhotoLibraryChangeObserver pozwala UI natychmiast reagować na zmiany w bibliotece multimediów.
  • Synchronizacja iCloud jest wbudowana w framework: pobranie obrazu automatycznie ładuje go z iCloud z postępem.
  • Optymalizacja — odpowiedni targetSize, anulowanie zapytań i ograniczenie iCloud podczas przewijania są krytyczne dla wydajności.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również