PhotoKit es un framework de Apple para trabajar con la librería multimedia en iOS y macOS, que proporciona acceso directo a fotos, videos y Live Photos en el dispositivo. Según la documentación de Apple, el framework reemplaza al obsoleto AssetsLibrary y admite iCloud, álbumes, edición y Change Tracking. PhotoKit proporciona una API unificada para consultas, almacenamiento en caché y cambios en la librería multimedia con sincronización automática a través de iCloud.
Puntos clave
PhotoKit es un framework de Apple (presentado en iOS 8, macOS 10.11) que proporciona una API orientada a objetos para trabajar con la librería multimedia del sistema. A diferencia de AssetsLibrary, PhotoKit trata la librería multimedia como una base de datos: las consultas devuelven objetos PHAsset, PHCollection y PHCollectionList que representan el contenido y la estructura de almacenamiento.
PhotoKit admite todos los tipos de medios: fotos (JPEG, HEIF, RAW), videos (MOV, MP4), Live Photos y ráfagas de fotos. El framework gestiona automáticamente la sincronización de iCloud: si una imagen está almacenada en iCloud, PhotoKit la solicita a través de la red e informa del progreso mediante PHImageRequestOptions.progressHandler.
Una característica clave de PhotoKit es el modelo de datos basado en PHObject con un identificador local (localIdentifier) que permanece estable entre sesiones. Esto permite guardar referencias a objetos multimedia y restaurarlos después de reiniciar la aplicación sin necesidad de volver a consultarlos.
PhotoKit se basa en tres niveles: modelo de datos (PHObject), consultas (PHFetchResult) y cambios (PHPhotoLibrary.performChanges). El modelo de datos es jerárquico: PHAsset (foto/video) se encuentra dentro de PHAssetCollection (álbum), y los álbumes se agrupan en PHCollectionList (carpeta).
Las consultas se ejecutan a través de PHAsset.fetchAssets y PHAssetCollection.fetchAssetCollections. Todos los métodos fetch son síncronos y devuelven PHFetchResult, que ejecuta inmediatamente la consulta contra la base de datos de la librería multimedia. PHFetchResult admite acceso rápido por índice (object(at:)) y enumeración mediante enumerateObjects.
PHFetchOptions es un objeto para configurar consultas: ordenación (sortDescriptors), predicado (predicate), inclusión de medios ocultos y eliminados (includeHiddenAssets, includeAllBurstAssets). Las opciones de fetch permiten filtrar por tipo de medio: PHAssetMediaType.image, .video, .audio.
PhotoKit incluye un conjunto de clases para acceder, consultar y modificar la librería multimedia. Comprender cada una de ellas es esencial para trabajar eficazmente con el framework.
PHAsset es un objeto inmutable que representa un único elemento multimedia. Contiene metadatos: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (para video), isFavorite, burstIdentifier. LocalIdentifier es una clave de cadena estable accesible incluso después de reiniciar la aplicación.
PHAssetCollection es un grupo de medios: álbumes del sistema (Recents, Favorites, Selfies, Screenshots), álbumes de usuario o Moments (agrupados automáticamente por tiempo y lugar). Atributos: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList es una carpeta que contiene álbumes (PHAssetCollection) u otras carpetas. Se usa con poca frecuencia, principalmente para mostrar la jerarquía en la interfaz de usuario.
PhotoKit no devuelve UIImage directamente desde PHAsset — es necesario solicitar una imagen a través de PHImageManager. Esto garantiza que la imagen se cargue con soporte de iCloud, almacenamiento en caché y el tamaño requerido.
| Componente | Propósito | Característica |
|---|---|---|
| PHImageManager.default() | Gestor estándar para solicitudes únicas | Sin caché entre solicitudes |
| PHCachingImageManager | Gestor con precarga para colecciones | startCachingImages para desplazamiento suave |
| PHImageRequestOptions | Configuración de solicitud: tamaño, modo, entrega | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Identificador de solicitud para cancelación | cancelImageRequest(PHImageRequestID) |
PHImageManager admite tres modos de entrega: opportunistic (primero una versión reducida, luego la completa), highQualityFormat (solo calidad completa) y fastFormat (versión más rápida disponible). Para colecciones, use siempre PHCachingImageManager con precarga de imágenes para las celdas visibles.
PhotoKit se utiliza para crear galerías personalizadas, editores y aplicaciones multimedia. Veamos tres escenarios clave.
PHAsset.fetchAssets con PHFetchOptions ordenado por fecha de creación es la consulta básica para construir una galería de fotos personalizada. PHFetchResult admite carga diferida y acceso 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("Found \(allPhotos.count) photos")
allPhotos.enumerateObjects { asset, index, stop in
print("Photo \(index): \(asset.localIdentifier)")
}
PHFetchResult es un contenedor thread-safe. Acceder a objetos por índice mediante object(at:) no bloquea la UI, pero solicitar una imagen a través de PHImageManager debe hacerse de forma asíncrona.
PHCachingImageManager es una subclase de PHImageManager con métodos startCachingImages y stopCachingImages para precarga. Se usa en UICollectionView para un desplazamiento suave.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Precarga para celdas visibles
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Solicitar imagen a través de PHImageRequestOptions con fallback de iCloud
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)")
}
Los cambios en la librería multimedia se realizan a través de PHPhotoLibrary.shared().performChanges dentro de un bloque changeRequest. Todas las operaciones se agrupan y se aplican de forma transaccional.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Added to favorites")
}
}
PhotoKit proporciona un mecanismo para observar los cambios en la librería multimedia a través del protocolo PHPhotoLibraryChangeObserver. Cuando se producen cambios (creación, eliminación, edición), se llama al método photoLibraryDidChange con un objeto PHChange.
PHChange contiene changeDetails para cada tipo de consulta: PHFetchResultChangeDetails con removedIndexes, insertedIndexes, changedIndexes. Esto permite aplicar cambios a la UI con animación: performBatchUpdates con move, insert, delete para 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
// Aplicar cambios a collectionView
}
}
}
PhotoKit admite la edición de medios a través del mecanismo PHContentEditingInput y PHContentEditingOutput. La aplicación solicita editingInput con los datos originales, aplica cambios y guarda el resultado mediante editingOutput. El framework conserva automáticamente el original, permitiendo a los usuarios revertir los cambios restableciendo el original.
Las fotos RAW (DNG, CR2, NEF) se admiten a través de PHAssetResourceManager, que proporciona acceso al archivo RAW original. Para el procesamiento RAW, se recomienda usar CoreImage con el filtro CIRAWFilter, que permite ajustar temperatura, exposición y nitidez. PhotoKit también admite extensiones de editor a través de Photo Editing Extension (iOS): una aplicación puede ser invocada desde el editor del sistema para procesar una foto o video seleccionado.
PhotoKit es un framework potente pero que consume muchos recursos. Un uso incorrecto puede provocar ralentizaciones al desplazarse y un consumo excesivo de memoria. Siga estas recomendaciones para un rendimiento óptimo.
PHLivePhoto requiere una solicitud separada a través de PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). No solicite Live Photo para celdas que solo muestran fotos — use PHLivePhotoBadge como indicador.
Preguntas frecuentes
PhotoKit es un framework moderno de Apple para trabajar con la librería multimedia, presentado en iOS 8. A diferencia del obsoleto AssetsLibrary, PhotoKit proporciona el modelo de objetos PHAsset, PHFetchResult con búsqueda rápida, soporte de iCloud y Change Tracking para observar cambios.
Llame a PHPhotoLibrary.requestAuthorization(for: .readWrite) con un manejador de devolución de llamada. Después de recibir el estado .authorized, puede ejecutar consultas PHAsset.fetchAssets. El acceso de escritura requiere permiso .readWrite. Para solo lectura — .addOnly.
Use PHImageManager.default().requestImage con parámetros: asset, targetSize, contentMode y PHImageRequestOptions. El método asíncrono devuelve PHImageRequestID, que permite cancelar la solicitud. Para colecciones, use PHCachingImageManager con precarga.
Registre un observador mediante PHPhotoLibrary.shared().register(self) e implemente el protocolo PHPhotoLibraryChangeObserver. En el método photoLibraryDidChange, reciba PHChange con changeDetails para cada fetchResult y aplique cambios a la UI con animación.
En PHImageRequestOptions, establezca isNetworkAccessAllowed = true y un progressHandler para rastrear el progreso de descarga de iCloud. Durante el desplazamiento rápido, desactive el acceso a la red y cargue solo versiones locales para evitar retrasos.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también