PhotoKit é um framework da Apple para trabalhar com a biblioteca de mídia no iOS e macOS, fornecendo acesso direto a fotos, vídeos e Live Photos no dispositivo. De acordo com a documentação da Apple, o framework substitui o legado AssetsLibrary e suporta iCloud, álbuns, edição e Change Tracking. PhotoKit fornece uma API unificada para consultas, cache e alterações na biblioteca de mídia com sincronização automática via iCloud.
Pontos principais
PhotoKit é um framework da Apple (apresentado no iOS 8, macOS 10.11) que fornece uma API orientada a objetos para trabalhar com a biblioteca de mídia do sistema. Ao contrário do AssetsLibrary, o PhotoKit trata a biblioteca de mídia como um banco de dados: as consultas retornam objetos PHAsset, PHCollection e PHCollectionList que representam o conteúdo e a estrutura de armazenamento.
O PhotoKit suporta todos os tipos de mídia: fotos (JPEG, HEIF, RAW), vídeos (MOV, MP4), Live Photos e fotos em ráfaga. O framework gerencia automaticamente a sincronização do iCloud: se uma imagem estiver armazenada no iCloud, o PhotoKit a solicita pela rede e informa o progresso via PHImageRequestOptions.progressHandler.
Uma característica fundamental do PhotoKit é o modelo de dados baseado em PHObject com um identificador local (localIdentifier) que permanece estável entre sessões. Isso permite salvar referências a objetos de mídia e restaurá-los após reiniciar o aplicativo sem nova consulta.
O PhotoKit é construído em três níveis: modelo de dados (PHObject), consultas (PHFetchResult) e alterações (PHPhotoLibrary.performChanges). O modelo de dados é hierárquico: PHAsset (foto/vídeo) reside dentro de PHAssetCollection (álbum), e os álbuns são agrupados em PHCollectionList (pasta).
As consultas são executadas via PHAsset.fetchAssets e PHAssetCollection.fetchAssetCollections. Todos os métodos fetch são síncronos e retornam PHFetchResult, que executa imediatamente a consulta no banco de dados da biblioteca de mídia. O PHFetchResult suporta acesso rápido por índice (object(at:)) e enumeração via enumerateObjects.
PHFetchOptions é um objeto para configurar consultas: classificação (sortDescriptors), predicado (predicate), inclusão de mídia oculta e excluída (includeHiddenAssets, includeAllBurstAssets). As opções de fetch permitem filtrar por tipo de mídia: PHAssetMediaType.image, .video, .audio.
O PhotoKit inclui um conjunto de classes para acessar, consultar e modificar a biblioteca de mídia. Compreender cada uma delas é essencial para trabalhar eficazmente com o framework.
PHAsset é um objeto imutável que representa um único item de mídia. Contém metadados: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (para vídeo), isFavorite, burstIdentifier. LocalIdentifier é uma chave de string estável acessível mesmo após reiniciar o aplicativo.
PHAssetCollection é um grupo de mídia: álbuns do sistema (Recents, Favorites, Selfies, Screenshots), álbuns de usuário ou Moments (agrupados automaticamente por tempo e local). Atributos: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList é uma pasta contendo álbuns (PHAssetCollection) ou outras pastas. É raramente usado, principalmente para exibir hierarquia na interface do usuário.
O PhotoKit não retorna UIImage diretamente do PHAsset — é necessário solicitar uma imagem via PHImageManager. Isso garante que a imagem seja carregada com suporte a iCloud, cache e tamanho necessário.
| Componente | Finalidade | Característica |
|---|---|---|
| PHImageManager.default() | Gerenciador padrão para solicitações únicas | Sem cache entre solicitações |
| PHCachingImageManager | Gerenciador com pré-carregamento para coleções | startCachingImages para rolagem suave |
| PHImageRequestOptions | Configurações de solicitação: tamanho, modo, entrega | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Identificador de solicitação para cancelamento | cancelImageRequest(PHImageRequestID) |
O PHImageManager suporta três modos de entrega: opportunistic (primeiro uma versão reduzida, depois a completa), highQualityFormat (apenas qualidade total) e fastFormat (versão mais rápida disponível). Para coleções, sempre use PHCachingImageManager com pré-carregamento de imagens para as células visíveis.
O PhotoKit é usado para criar galerias personalizadas, editores e aplicativos de mídia. Vamos analisar três cenários principais.
PHAsset.fetchAssets com PHFetchOptions ordenado por data de criação é a consulta básica para construir uma galeria de fotos personalizada. O PHFetchResult suporta carregamento lento e acesso em 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("Encontradas \(allPhotos.count) fotos")
allPhotos.enumerateObjects { asset, index, stop in
print("Foto \(index): \(asset.localIdentifier)")
}
PHFetchResult é um contêiner thread-safe. Acessar objetos por índice via object(at:) não bloqueia a UI, mas solicitar uma imagem via PHImageManager deve ser feito de forma assíncrona.
PHCachingImageManager é uma subclasse de PHImageManager com métodos startCachingImages e stopCachingImages para pré-carregamento. É usado em UICollectionView para rolagem suave.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Pré-carregamento para células visíveis
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Solicitar imagem via PHImageRequestOptions com fallback do 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)")
}
As alterações na biblioteca de mídia são realizadas via PHPhotoLibrary.shared().performChanges dentro de um bloco changeRequest. Todas as operações são agrupadas e aplicadas de forma transacional.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Adicionado aos favoritos")
}
}
O PhotoKit fornece um mecanismo para observar alterações na biblioteca de mídia através do protocolo PHPhotoLibraryChangeObserver. Quando ocorrem alterações (criação, exclusão, edição), o método photoLibraryDidChange é chamado com um objeto PHChange.
PHChange contém changeDetails para cada tipo de consulta: PHFetchResultChangeDetails com removedIndexes, insertedIndexes, changedIndexes. Isso permite aplicar alterações na UI com animação: performBatchUpdates com 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 alterações ao collectionView
}
}
}
O PhotoKit suporta edição de mídia através do mecanismo PHContentEditingInput e PHContentEditingOutput. O aplicativo solicita editingInput com dados originais, aplica alterações e salva o resultado via editingOutput. O framework preserva automaticamente o original, permitindo que os usuários revertam as alterações redefinindo para o original.
Fotos RAW (DNG, CR2, NEF) são suportadas via PHAssetResourceManager, que fornece acesso ao arquivo RAW original. Para processamento RAW, recomenda-se usar CoreImage com o filtro CIRAWFilter, que suporta ajuste de temperatura, exposição e nitidez. O PhotoKit também suporta extensões de editor via Photo Editing Extension (iOS) — um aplicativo pode ser invocado a partir do editor do sistema para processar uma foto ou vídeo selecionado.
O PhotoKit é um framework poderoso, mas que consome muitos recursos. O uso incorreto pode causar lentidão na rolagem e consumo excessivo de memória. Siga estas recomendações para obter desempenho ideal.
PHLivePhoto requer uma solicitação separada via PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Não solicite Live Photo para células que exibem apenas fotos — use PHLivePhotoBadge como indicador.
Perguntas frequentes
PhotoKit é um framework moderno da Apple para trabalhar com a biblioteca de mídia, apresentado no iOS 8. Ao contrário do legado AssetsLibrary, o PhotoKit fornece o modelo de objetos PHAsset, PHFetchResult com busca rápida, suporte a iCloud e Change Tracking para observar alterações.
Chame PHPhotoLibrary.requestAuthorization(for: .readWrite) com um manipulador de callback. Após receber o status .authorized, você pode executar consultas PHAsset.fetchAssets. O acesso de escrita requer permissão .readWrite. Para somente leitura — .addOnly.
Use PHImageManager.default().requestImage com parâmetros: asset, targetSize, contentMode e PHImageRequestOptions. O método assíncrono retorna PHImageRequestID, permitindo cancelar a solicitação. Para coleções, use PHCachingImageManager com pré-carregamento.
Registre um observador via PHPhotoLibrary.shared().register(self) e implemente o protocolo PHPhotoLibraryChangeObserver. No método photoLibraryDidChange, receba PHChange com changeDetails para cada fetchResult e aplique alterações na UI com animação.
Em PHImageRequestOptions, defina isNetworkAccessAllowed = true e um progressHandler para rastrear o progresso do download do iCloud. Durante a rolagem rápida, desative o acesso à rede e carregue apenas versões locais para evitar atrasos na rolagem.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também