PhotoKit est un framework Apple pour travailler avec la médiathèque sur iOS et macOS, offrant un accès direct aux photos, vidéos et Live Photos sur l’appareil. Selon la documentation Apple, le framework remplace l’ancien AssetsLibrary et prend en charge iCloud, les albums, l’édition et le Change Tracking. PhotoKit fournit une API unifiée pour les requêtes, la mise en cache et les modifications de la médiathèque avec synchronisation automatique via iCloud.
Points clés
PhotoKit est un framework Apple (présenté dans iOS 8, macOS 10.11) qui fournit une API orientée objet pour travailler avec la médiathèque système. Contrairement à AssetsLibrary, PhotoKit traite la médiathèque comme une base de données : les requêtes retournent des objets PHAsset, PHCollection et PHCollectionList représentant le contenu et la structure de stockage.
PhotoKit prend en charge tous les types de médias : photos (JPEG, HEIF, RAW), vidéos (MOV, MP4), Live Photos et photos en rafale. Le framework gère automatiquement la synchronisation iCloud : si une image est stockée dans iCloud, PhotoKit la demande via le réseau et signale la progression via PHImageRequestOptions.progressHandler.
Une caractéristique clé de PhotoKit est le modèle de données basé sur PHObject avec un identifiant local (localIdentifier) qui reste stable entre les sessions. Cela permet de sauvegarder des références vers des objets multimédias et de les restaurer après un redémarrage de l’application sans nouvelle requête.
PhotoKit est construit sur trois niveaux : modèle de données (PHObject), requêtes (PHFetchResult) et modifications (PHPhotoLibrary.performChanges). Le modèle de données est hiérarchique : PHAsset (photo/vidéo) se trouve dans PHAssetCollection (album), et les albums sont regroupés dans PHCollectionList (dossier).
Les requêtes sont exécutées via PHAsset.fetchAssets et PHAssetCollection.fetchAssetCollections. Toutes les méthodes fetch sont synchrones et retournent PHFetchResult, qui exécute immédiatement la requête dans la base de données de la médiathèque. PHFetchResult prend en charge l’accès rapide par index (object(at:)) et l’énumération via enumerateObjects.
PHFetchOptions est un objet pour configurer les requêtes : tri (sortDescriptors), prédicat (predicate), inclusion des médias cachés et supprimés (includeHiddenAssets, includeAllBurstAssets). Les options de fetch permettent de filtrer par type de média : PHAssetMediaType.image, .video, .audio.
PhotoKit comprend un ensemble de classes pour accéder, interroger et modifier la médiathèque. Comprendre chacune d’elles est essentiel pour travailler efficacement avec le framework.
PHAsset est un objet immuable représentant un élément multimédia unique. Il contient des métadonnées : mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (pour la vidéo), isFavorite, burstIdentifier. LocalIdentifier est une clé de chaîne stable accessible même après un redémarrage de l’application.
PHAssetCollection est un groupe de médias : albums système (Recents, Favorites, Selfies, Screenshots), albums utilisateur ou Moments (regroupés automatiquement par temps et lieu). Attributs : localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList est un dossier contenant des albums (PHAssetCollection) ou d’autres dossiers. Il est rarement utilisé, principalement pour afficher la hiérarchie dans l’interface utilisateur.
PhotoKit ne retourne pas UIImage directement depuis PHAsset — vous devez demander une image via PHImageManager. Cela garantit que l’image est chargée avec le support iCloud, la mise en cache et la taille requise.
| Composant | Objectif | Caractéristique |
|---|---|---|
| PHImageManager.default() | Gestionnaire standard pour les requêtes uniques | Aucune mise en cache entre les requêtes |
| PHCachingImageManager | Gestionnaire avec préchargement pour les collections | startCachingImages pour un défilement fluide |
| PHImageRequestOptions | Paramètres de requête : taille, mode, livraison | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Identifiant de requête pour annulation | cancelImageRequest(PHImageRequestID) |
PHImageManager prend en charge trois modes de livraison : opportunistic (d’abord une version réduite, puis la version complète), highQualityFormat (qualité complète uniquement) et fastFormat (version la plus rapide disponible). Pour les collections, utilisez toujours PHCachingImageManager avec préchargement des images pour les cellules visibles.
PhotoKit est utilisé pour créer des galeries personnalisées, des éditeurs et des applications multimédias. Examinons trois scénarios clés.
PHAsset.fetchAssets avec PHFetchOptions trié par date de création est la requête de base pour construire une galerie photo personnalisée. PHFetchResult prend en charge le chargement paresseux et l’accès en streaming.
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) photos trouvées")
allPhotos.enumerateObjects { asset, index, stop in
print("Photo \(index) : \(asset.localIdentifier)")
}
PHFetchResult est un conteneur thread-safe. L’accès aux objets par index via object(at:) ne bloque pas l’interface utilisateur, mais la demande d’image via PHImageManager doit être effectuée de manière asynchrone.
PHCachingImageManager est une sous-classe de PHImageManager avec les méthodes startCachingImages et stopCachingImages pour le préchargement. Il est utilisé dans UICollectionView pour un défilement fluide.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Préchargement pour les cellules visibles
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Demande d’image via PHImageRequestOptions avec repli iCloud
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("Téléchargement depuis iCloud : \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("Image obtenue : \(image?.size ?? .zero)")
}
Les modifications de la médiathèque sont effectuées via PHPhotoLibrary.shared().performChanges dans un bloc changeRequest. Toutes les opérations sont regroupées et appliquées de manière transactionnelle.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Ajouté aux favoris")
}
}
PhotoKit fournit un mécanisme d’observation des modifications de la médiathèque via le protocole PHPhotoLibraryChangeObserver. Lorsque des modifications surviennent (création, suppression, édition), la méthode photoLibraryDidChange est appelée avec un objet PHChange.
PHChange contient changeDetails pour chaque type de requête : PHFetchResultChangeDetails avec removedIndexes, insertedIndexes, changedIndexes. Cela permet d’appliquer les modifications à l’interface utilisateur avec animation : performBatchUpdates avec move, insert, delete pour 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
// Appliquer les modifications au collectionView
}
}
}
PhotoKit prend en charge l’édition de médias via le mécanisme PHContentEditingInput et PHContentEditingOutput. L’application demande editingInput avec les données originales, applique les modifications et enregistre le résultat via editingOutput. Le framework conserve automatiquement l’original, permettant aux utilisateurs d’annuler les modifications en réinitialisant l’original.
Les photos RAW (DNG, CR2, NEF) sont prises en charge via PHAssetResourceManager, qui fournit un accès au fichier RAW original. Pour le traitement RAW, il est recommandé d’utiliser CoreImage avec le filtre CIRAWFilter, qui prend en charge le réglage de la température, de l’exposition et de la netteté. PhotoKit prend également en charge les extensions d’éditeur via Photo Editing Extension (iOS) — une application peut être invoquée depuis l’éditeur système pour traiter une photo ou une vidéo sélectionnée.
PhotoKit est un framework puissant mais gourmand en ressources. Une utilisation incorrecte peut entraîner des ralentissements lors du défilement et une consommation excessive de mémoire. Suivez ces recommandations pour des performances optimales.
PHLivePhoto nécessite une requête séparée via PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Ne demandez pas Live Photo pour les cellules qui n’affichent que des photos — utilisez PHLivePhotoBadge comme indicateur.
Foire aux questions
PhotoKit est un framework Apple moderne pour travailler avec la médiathèque, présenté dans iOS 8. Contrairement à l’ancien AssetsLibrary, PhotoKit fournit le modèle d’objet PHAsset, PHFetchResult avec recherche rapide, support iCloud et Change Tracking pour observer les modifications.
Appelez PHPhotoLibrary.requestAuthorization(for: .readWrite) avec un gestionnaire de rappel. Après avoir reçu le statut .authorized, vous pouvez exécuter des requêtes PHAsset.fetchAssets. L’accès en écriture nécessite l’autorisation .readWrite. Pour la lecture seule — .addOnly.
Utilisez PHImageManager.default().requestImage avec les paramètres : asset, targetSize, contentMode et PHImageRequestOptions. La méthode asynchrone retourne PHImageRequestID, permettant d’annuler la requête. Pour les collections, utilisez PHCachingImageManager avec préchargement.
Enregistrez un observateur via PHPhotoLibrary.shared().register(self) et implémentez le protocole PHPhotoLibraryChangeObserver. Dans la méthode photoLibraryDidChange, recevez PHChange avec changeDetails pour chaque fetchResult et appliquez les modifications à l’interface utilisateur avec animation.
Dans PHImageRequestOptions, définissez isNetworkAccessAllowed = true et un progressHandler pour suivre la progression du téléchargement iCloud. Pendant le défilement rapide, désactivez l’accès réseau et chargez uniquement les versions locales pour éviter les ralentissements.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi