PhotoKit ist ein Apple-Framework für die Arbeit mit der Medienbibliothek unter iOS und macOS und bietet direkten Zugriff auf Fotos, Videos und Live Photos auf dem Gerät. Laut Apple-Dokumentation ersetzt das Framework die veraltete AssetsLibrary und unterstützt iCloud, Alben, Bearbeitung und Change Tracking. PhotoKit bietet eine einheitliche API für Abfragen, Zwischenspeicherung und Änderungen der Medienbibliothek mit automatischer Synchronisation über iCloud.
Wichtige Punkte
PhotoKit ist ein Apple-Framework (eingeführt in iOS 8, macOS 10.11), das eine objektorientierte API für die Arbeit mit der systemeigenen Medienbibliothek bereitstellt. Im Gegensatz zu AssetsLibrary behandelt PhotoKit die Medienbibliothek als Datenbank: Abfragen geben PHAsset-, PHCollection- und PHCollectionList-Objekte zurück, die den Inhalt und die Speicherstruktur repräsentieren.
PhotoKit unterstützt alle Medientypen: Fotos (JPEG, HEIF, RAW), Videos (MOV, MP4), Live Photos und Serienaufnahmen. Das Framework verwaltet die iCloud-Synchronisation automatisch: Wenn ein Bild in iCloud gespeichert ist, fordert PhotoKit es über das Netzwerk an und meldet den Fortschritt über PHImageRequestOptions.progressHandler.
Eine Schlüsselfunktion von PhotoKit ist das auf PHObject basierende Datenmodell mit einer lokalen Kennung (localIdentifier), die zwischen Sitzungen stabil bleibt. Dadurch können Sie Referenzen auf Medienobjekte speichern und nach einem Neustart der App wiederherstellen, ohne erneut abfragen zu müssen.
PhotoKit ist auf drei Ebenen aufgebaut: Datenmodell (PHObject), Abfragen (PHFetchResult) und Änderungen (PHPhotoLibrary.performChanges). Das Datenmodell ist hierarchisch: PHAsset (Foto/Video) befindet sich innerhalb von PHAssetCollection (Album), und Alben werden in PHCollectionList (Ordner) gruppiert.
Abfragen werden über PHAsset.fetchAssets und PHAssetCollection.fetchAssetCollections ausgeführt. Alle Fetch-Methoden sind synchron und geben PHFetchResult zurück, das sofort die Abfrage gegen die Datenbank der Medienbibliothek ausführt. PHFetchResult unterstützt schnellen Indexzugriff (object(at:)) und Aufzählung über enumerateObjects.
PHFetchOptions ist ein Objekt zum Konfigurieren von Abfragen: Sortierung (sortDescriptors), Prädikat (predicate), Einbeziehung ausgeblendeter und gelöschter Medien (includeHiddenAssets, includeAllBurstAssets). Fetch-Optionen ermöglichen das Filtern nach Medientyp: PHAssetMediaType.image, .video, .audio.
PhotoKit enthält eine Reihe von Klassen für den Zugriff auf, die Abfrage und die Änderung der Medienbibliothek. Das Verständnis jeder einzelnen ist für die effektive Arbeit mit dem Framework unerlässlich.
PHAsset ist ein unveränderliches Objekt, das ein einzelnes Medienelement darstellt. Es enthält Metadaten: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (für Video), isFavorite, burstIdentifier. LocalIdentifier ist ein stabiler Zeichenfolgeschlüssel, der auch nach einem Neustart der App zugänglich ist.
PHAssetCollection ist eine Gruppe von Medien: Systemalben (Recents, Favorites, Selfies, Screenshots), Benutzeralben oder Moments (automatisch nach Zeit und Ort gruppiert). Attribute: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList ist ein Ordner, der Alben (PHAssetCollection) oder andere Ordner enthält. Er wird selten verwendet, hauptsächlich zur Anzeige der Hierarchie in der Benutzeroberfläche.
PhotoKit gibt kein UIImage direkt von PHAsset zurück — Sie müssen ein Bild über PHImageManager anfordern. Dadurch wird sichergestellt, dass das Bild mit iCloud-Unterstützung, Zwischenspeicherung und der erforderlichen Größe geladen wird.
| Komponente | Zweck | Besonderheit |
|---|---|---|
| PHImageManager.default() | Standard-Manager für einmalige Anfragen | Keine Zwischenspeicherung zwischen Anfragen |
| PHCachingImageManager | Manager mit Vorabruf für Sammlungen | startCachingImages für flüssiges Scrollen |
| PHImageRequestOptions | Anfrageeinstellungen: Größe, Modus, Zustellung | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Anfragekennung zum Abbrechen | cancelImageRequest(PHImageRequestID) |
PHImageManager unterstützt drei Zustellmodi: opportunistic (zuerst eine reduzierte Version, dann die vollständige), highQualityFormat (nur volle Qualität) und fastFormat (schnellste verfügbare Version). Verwenden Sie für Sammlungen immer PHCachingImageManager mit Bildvorabruf für sichtbare Zellen.
PhotoKit wird zum Erstellen benutzerdefinierter Galerien, Editoren und Medienanwendungen verwendet. Betrachten wir drei wichtige Szenarien.
PHAsset.fetchAssets mit nach Erstellungsdatum sortierten PHFetchOptions ist die grundlegende Abfrage zum Erstellen einer benutzerdefinierten Fotogalerie. PHFetchResult unterstützt Lazy Loading und Streaming-Zugriff.
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) Fotos gefunden")
allPhotos.enumerateObjects { asset, index, stop in
print("Foto \(index): \(asset.localIdentifier)")
}
PHFetchResult ist ein thread-sicherer Container. Der Zugriff auf Objekte per Index über object(at:) blockiert nicht die UI, aber das Anfordern eines Bildes über PHImageManager sollte asynchron erfolgen.
PHCachingImageManager ist eine Unterklasse von PHImageManager mit den Methoden startCachingImages und stopCachingImages zum Vorabruf. Es wird in UICollectionView für flüssiges Scrollen verwendet.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Vorabruf für sichtbare Zellen
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Bildanfrage über PHImageRequestOptions mit iCloud-Fallback
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("Downloading from iCloud: \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("Got image: \(image?.size ?? .zero)")
}
Änderungen an der Medienbibliothek werden über PHPhotoLibrary.shared().performChanges innerhalb eines changeRequest-Blocks durchgeführt. Alle Operationen werden gebündelt und transaktional angewendet.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Zu Favoriten hinzugefügt")
}
}
PhotoKit bietet einen Mechanismus zur Beobachtung von Änderungen an der Medienbibliothek über das Protokoll PHPhotoLibraryChangeObserver. Wenn Änderungen auftreten (Erstellung, Löschung, Bearbeitung), wird die Methode photoLibraryDidChange mit einem PHChange-Objekt aufgerufen.
PHChange enthält changeDetails für jeden Abfragetyp: PHFetchResultChangeDetails mit removedIndexes, insertedIndexes, changedIndexes. Dies ermöglicht das Anwenden von Änderungen an der UI mit Animation: performBatchUpdates mit move, insert, delete für 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
// Änderungen an collectionView übernehmen
}
}
}
PhotoKit unterstützt die Medienbearbeitung über den Mechanismus PHContentEditingInput und PHContentEditingOutput. Die App fordert editingInput mit den Originaldaten an, wendet Änderungen an und speichert das Ergebnis über editingOutput. Das Framework bewahrt automatisch das Original, sodass Benutzer Änderungen durch Zurücksetzen auf das Original rückgängig machen können.
RAW-Fotos (DNG, CR2, NEF) werden über PHAssetResourceManager unterstützt, der Zugriff auf die originale RAW-Datei bietet. Für die RAW-Verarbeitung wird die Verwendung von CoreImage mit dem CIRAWFilter empfohlen, der die Anpassung von Temperatur, Belichtung und Schärfe unterstützt. PhotoKit unterstützt auch Editor-Erweiterungen über Photo Editing Extension (iOS) — eine App kann aus dem Systemeditor aufgerufen werden, um ein ausgewähltes Foto oder Video zu verarbeiten.
PhotoKit ist ein leistungsstarkes, aber ressourcenintensives Framework. Unsachgemäße Verwendung kann zu Scroll-Verzögerungen und übermäßigem Speicherverbrauch führen. Befolgen Sie diese Empfehlungen für optimale Leistung.
PHLivePhoto erfordert eine separate Anfrage über PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Fordern Sie kein Live Photo für Zellen an, die nur Fotos anzeigen — verwenden Sie PHLivePhotoBadge als Indikator.
Häufig gestellte Fragen
PhotoKit ist ein modernes Apple-Framework für die Arbeit mit der Medienbibliothek, eingeführt in iOS 8. Im Gegensatz zur veralteten AssetsLibrary bietet PhotoKit das PHAsset-Objektmodell, PHFetchResult mit schneller Suche, iCloud-Unterstützung und Change Tracking zur Beobachtung von Änderungen.
Rufen Sie PHPhotoLibrary.requestAuthorization(for: .readWrite) mit einem Callback-Handler auf. Nach Erhalt des Status .authorized können Sie PHAsset.fetchAssets-Abfragen ausführen. Schreibzugriff erfordert die Berechtigung .readWrite. Für Schreibgeschützt — .addOnly.
Verwenden Sie PHImageManager.default().requestImage mit Parametern: asset, targetSize, contentMode und PHImageRequestOptions. Die asynchrone Methode gibt PHImageRequestID zurück, mit der Sie die Anfrage abbrechen können. Für Sammlungen verwenden Sie PHCachingImageManager mit Vorabruf.
Registrieren Sie einen Beobachter über PHPhotoLibrary.shared().register(self) und implementieren Sie das Protokoll PHPhotoLibraryChangeObserver. In der Methode photoLibraryDidChange erhalten Sie PHChange mit changeDetails für jedes fetchResult und wenden Änderungen mit Animation auf die UI an.
Setzen Sie in PHImageRequestOptions isNetworkAccessAllowed = true und einen progressHandler zur Verfolgung des iCloud-Download-Fortschritts. Deaktivieren Sie während des schnellen Scrollens den Netzwerkzugriff und laden Sie nur lokale Versionen, um Scroll-Verzögerungen zu vermeiden.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch