PhotoKit — je framework Apple pro práci s knihovnou médií na iOS a macOS, poskytující přímý přístup k fotkám, videům a Live Photos na zařízení. Podle dokumentace Apple framework nahrazuje zastaralý AssetsLibrary a podporuje iCloud, alba, úpravy a Change Tracking. PhotoKit poskytuje jednotné API pro dotazy, ukládání do mezipaměti a změny knihovny médií s automatickou synchronizací přes iCloud.
Hlavní body
PhotoKit — framework Apple (představen v iOS 8, macOS 10.11), poskytující objektově orientované API pro práci se systémovou knihovnou médií. Na rozdíl od AssetsLibrary pracuje PhotoKit s knihovnou médií jako s databází: dotazy vracejí objekty PHAsset, PHCollection, PHCollectionList, představující obsah a strukturu úložiště.
PhotoKit podporuje všechny typy médií: fotografie (JPEG, HEIF, RAW), videa (MOV, MP4), Live Photos a sériové snímky. Framework automaticky spravuje synchronizaci iCloud: pokud je obrázek uložen v iCloud, PhotoKit ho vyžádá přes síť a hlásí průběh prostřednictvím PHImageRequestOptions.progressHandler.
Klíčovou vlastností PhotoKit je datový model založený na PHObject s lokálním identifikátorem (localIdentifier), který zůstává stabilní mezi relacemi. To umožňuje ukládat reference na mediální objekty a obnovovat je po restartu aplikace bez opakovaného dotazu.
PhotoKit je postaven na třech úrovních: datový model (PHObject), dotazy (PHFetchResult) a změny (PHPhotoLibrary.performChanges). Datový model je hierarchický: PHAsset (fotka/video) se nachází uvnitř PHAssetCollection (album), alba jsou seskupena do PHCollectionList (složka).
Dotazy se provádějí prostřednictvím PHAsset.fetchAssets a PHAssetCollection.fetchAssetCollections. Všechny metody fetch jsou synchronní a vracejí PHFetchResult, jehož objekt okamžitě provede dotaz do databáze knihovny médií. PHFetchResult podporuje rychlý přístup podle indexu (object(at:)) a výčet pomocí enumerateObjects.
PHFetchOptions — objekt pro konfiguraci dotazu: řazení (sortDescriptors), predikát (predicate), zahrnutí skrytých a smazaných médií (includeHiddenAssets, includeAllBurstAssets). Volby fetch umožňují filtrování podle typu média: PHAssetMediaType.image, .video, .audio.
PhotoKit obsahuje sadu tříd pro přístup, dotazy a změny knihovny médií. Porozumění každé z nich je nezbytné pro efektivní práci s frameworkem.
PHAsset — neměnný objekt představující jeden mediální obsah. Obsahuje metadata: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (pro video), isFavorite, burstIdentifier. LocalIdentifier — stabilní textový klíč, dostupný i po restartu aplikace.
PHAssetCollection — skupina médií: systémová alba (Recents, Favorites, Selfies, Screenshots), uživatelská alba nebo Moments (automaticky seskupené podle času a místa). Atributy: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList — složka obsahující alba (PHAssetCollection) nebo jiné složky. Používá se zřídka, hlavně pro zobrazení hierarchie v uživatelském rozhraní.
PhotoKit nevrací UIImage přímo z PHAsset — je třeba vyžádat obrázek prostřednictvím PHImageManager. To zaručuje, že obrázek je načten s ohledem na iCloud, ukládání do mezipaměti a požadovanou velikost.
| Komponent | Účel | Vlastnost |
|---|---|---|
| PHImageManager.default() | Standardní správce pro jednotlivé dotazy | Žádné ukládání do mezipaměti mezi dotazy |
| PHCachingImageManager | Správce s přednačítáním pro kolekce | startCachingImages pro plynulé scrollování |
| PHImageRequestOptions | Nastavení dotazu: velikost, režim, doručení | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Identifikátor dotazu pro zrušení | cancelImageRequest(PHImageRequestID) |
PHImageManager podporuje tři režimy doručení: opportunistic (nejprve zmenšená verze, poté plná), highQualityFormat (pouze plná kvalita) a fastFormat (nejrychlejší dostupná verze). Pro kolekce vždy používejte PHCachingImageManager s přednačítáním obrázků pro viditelné buňky.
PhotoKit se používá k vytváření vlastních galerií, editorů a aplikací pro práci s médii. Podívejme se na tři klíčové scénáře.
PHAsset.fetchAssets s PHFetchOptions a řazením podle data vytvoření — základní dotaz pro vytvoření vlastní fotogalerie. PHFetchResult podporuje líné načítání a proudový přístup.
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("Nalezeno \(allPhotos.count) fotografií")
allPhotos.enumerateObjects { asset, index, stop in
print("Fotografie \(index): \(asset.localIdentifier)")
}
PHFetchResult — thread-safe kontejner. Přístup k objektům podle indexu přes object(at:) neblokuje UI, ale vyžádání obrázku přes PHImageManager musí být provedeno asynchronně.
PHCachingImageManager — podtřída PHImageManager s metodami startCachingImages a stopCachingImages pro přednačítání. Používá se v UICollectionView pro plynulé scrollování.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Přednačítání pro viditelné buňky
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Vyžádání obrázku přes PHImageRequestOptions s iCloud fallback
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("Stahování z iCloud: \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("Obrázek přijat: \(image?.size ?? .zero)")
}
Změny v knihovně médií se provádějí prostřednictvím PHPhotoLibrary.shared().performChanges uvnitř bloku changeRequest. Všechny operace jsou dávkovány a aplikovány transakčně.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Přidáno do oblíbených")
}
}
PhotoKit poskytuje mechanismus sledování změn v knihovně médií prostřednictvím protokolu PHPhotoLibraryChangeObserver. Při jakékoliv změně (vytvoření, smazání, úprava) je volána metoda photoLibraryDidChange s objektem PHChange.
PHChange obsahuje changeDetails pro každý typ dotazu: PHFetchResultChangeDetails s removedIndexes, insertedIndexes, changedIndexes. To umožňuje aplikovat změny v UI s animací: performBatchUpdates s move, insert, delete pro 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
// Aplikovat změny na collectionView
}
}
}
PhotoKit podporuje úpravu médií prostřednictvím mechanismu PHContentEditingInput a PHContentEditingOutput. Aplikace vyžádá editingInput s původními daty, aplikuje změny a uloží výsledek přes editingOutput. Framework automaticky uchovává originál, což uživateli umožňuje vrátit změny resetem na originál.
RAW fotografie (DNG, CR2, NEF) jsou podporovány prostřednictvím PHAssetResourceManager, který poskytuje přístup k původnímu RAW souboru. Pro zpracování RAW se doporučuje použít CoreImage s filtrem CIRAWFilter, který podporuje nastavení teploty, expozice a ostrosti. PhotoKit také podporuje rozšíření editorů prostřednictvím Photo Editing Extension (iOS) — aplikace může být volána ze systémového editoru pro zpracování vybrané fotografie nebo videa.
PhotoKit — výkonný, ale náročný framework. Nesprávné použití může vést ke zpomalení při scrollování a nadměrné spotřebě paměti. Postupujte podle doporučení pro optimální výkon.
PHLivePhoto — vyžaduje samostatný dotaz prostřednictvím PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Nevyžadujte Live Photo pro buňky, kde se zobrazuje pouze fotografie — použijte PHLivePhotoBadge pro indikaci.
Často kladené otázky
PhotoKit — moderní framework Apple pro práci s knihovnou médií, představený v iOS 8. Na rozdíl od zastaralého AssetsLibrary poskytuje PhotoKit objektový model PHAsset, PHFetchResult s rychlým vyhledáváním, podporu iCloud a Change Tracking pro sledování změn.
Zavolejte PHPhotoLibrary.requestAuthorization(for: .readWrite) se zpracováním v callbacku. Po získání stavu .authorized můžete provádět dotazy PHAsset.fetchAssets. Pro zápis je vyžadován přístup .readWrite. Pro pouze čtení — .addOnly.
Použijte PHImageManager.default().requestImage s parametry: asset, targetSize, contentMode a PHImageRequestOptions. Asynchronní metoda vrací PHImageRequestID, umožňující zrušení dotazu. Pro kolekce použijte PHCachingImageManager s přednačítáním.
Zaregistrujte pozorovatele prostřednictvím PHPhotoLibrary.shared().register(self) a implementujte protokol PHPhotoLibraryChangeObserver. V metodě photoLibraryDidChange obdržíte PHChange s changeDetails pro každý fetchResult a aplikujte změny v UI s animací.
V PHImageRequestOptions nastavte isNetworkAccessAllowed = true a progressHandler pro sledování načítání z iCloud. Při rychlém scrollování vypněte síťový přístup a načítejte pouze lokální verze, abyste předešli zpožděním při scrollování.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také