PhotoKit — је Apple фрејмворк за рад са медијатеком на iOS и macOS-у, који пружа директан приступ фотографијама, видео записима и Live Photos на уређају. Према документацији Apple-а, фрејмворк замењује застарели AssetsLibrary и подржава iCloud, албуме, уређивање и Change Tracking. PhotoKit обезбеђује јединствени API за упите, кеширање и измене медијатеке са аутоматском синхронизацијом преко iCloud-а.
Главне тачке
PhotoKit — Apple фрејмворк (представљен у iOS 8, macOS 10.11), који пружа објектно-оријентисани API за рад са системском медијатеком. За разлику од AssetsLibrary-а, PhotoKit ради са медијатеком као са базом података: упити враћају објекте PHAsset, PHCollection, PHCollectionList, који представљају садржај и структуру складиштења.
PhotoKit подржава све типове медија: фотографије (JPEG, HEIF, RAW), видео записе (MOV, MP4), Live Photos и серијске снимке. Фрејмворк аутоматски управља iCloud синхронизацијом: ако се слика чува у iCloud-у, PhotoKit је захтева преко мреже и пријављује напредак кроз PHImageRequestOptions.progressHandler.
Кључна карактеристика PhotoKit-а — модел података заснован на PHObject-у са локалним идентификатором (localIdentifier), који остаје стабилан између сесија. Ово омогућава чување референци на медијске објекте и њихово обнављање након поновног покретања апликације без поновног упита.
PhotoKit је изграђен на три нивоа: модел података (PHObject), упити (PHFetchResult) и измене (PHPhotoLibrary.performChanges). Модел података је хијерархијски: PHAsset (фотографија/видео) налази се унутар PHAssetCollection (албум), албуми се групишу у PHCollectionList (фасцикла).
Упити се извршавају кроз PHAsset.fetchAssets и PHAssetCollection.fetchAssetCollections. Све fetch методе су синхроне и враћају PHFetchResult, чији објекат одмах извршава упит у бази података медијатеке. PHFetchResult подржава брзи приступ по индексу (object(at:)) и набрајање кроз enumerateObjects.
PHFetchOptions — објекат за конфигурацију упита: сортирање (sortDescriptors), предикат (predicate), укључивање скривених и избрисаних медија (includeHiddenAssets, includeAllBurstAssets). Fetch опције омогућавају филтрирање по типу медија: PHAssetMediaType.image, .video, .audio.
PhotoKit укључује скуп класа за приступ, упите и измене медијатеке. Разумевање сваке од њих је неопходно за ефикасан рад са фрејмворком.
PHAsset — непроменљиви објекат који представља један медијски садржај. Садржи метаподатке: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (за видео), isFavorite, burstIdentifier. LocalIdentifier — стабилни текстуални кључ, доступан чак и након поновног покретања апликације.
PHAssetCollection — група медија: системски албуми (Recents, Favorites, Selfies, Screenshots), кориснички албуми или Moments (аутоматски груписани по времену и месту). Атрибути: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList — фасцикла која садржи албуме (PHAssetCollection) или друге фасцикле. Ретко се користи, углавном за приказ хијерархије у корисничком интерфејсу.
PhotoKit не враћа UIImage директно из PHAsset-а — потребно је захтевати слику кроз PHImageManager. Ово гарантује да се слика учитава узимајући у обзир iCloud, кеширање и потребну величину.
| Компонента | Намена | Карактеристика |
|---|---|---|
| PHImageManager.default() | Стандардни менаџер за појединачне упите | Нема кеширања између упита |
| PHCachingImageManager | Менаџер са предучитавањем за колекције | startCachingImages за глатко скроловање |
| PHImageRequestOptions | Подешавања упита: величина, режим, испорука | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Идентификатор упита за отказивање | cancelImageRequest(PHImageRequestID) |
PHImageManager подржава три режима испоруке: opportunistic (прво смањена верзија, затим пуна), highQualityFormat (само пуни квалитет) и fastFormat (најбржа доступна верзија). За колекције увек користите PHCachingImageManager са предучитавањем слика за видљиве ћелије.
PhotoKit се користи за креирање прилагођених галерија, уређивача и апликација за рад са медијима. Размотримо три кључна сценарија.
PHAsset.fetchAssets са PHFetchOptions и сортирањем по датуму креирања — основни упит за изградњу прилагођене фото галерије. PHFetchResult подржава lazy-loading и стримовски приступ.
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) фотографија")
allPhotos.enumerateObjects { asset, index, stop in
print("Фотографија \(index): \(asset.localIdentifier)")
}
PHFetchResult — thread-safe контејнер. Приступ објектима по индексу кроз object(at:) не блокира UI, али захтев слике кроз PHImageManager мора да се изврши асинхроно.
PHCachingImageManager — подкласа PHImageManager-а са методама startCachingImages и stopCachingImages за предучитавање. Користи се у UICollectionView-у за глатко скроловање.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Предучитавање за видљиве ћелије
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Захтев слике кроз PHImageRequestOptions са iCloud fallback-ом
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("Преузимање са iCloud-а: \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("Слика примљена: \(image?.size ?? .zero)")
}
Измене у медијатеци се врше кроз PHPhotoLibrary.shared().performChanges унутар changeRequest блока. Све операције се групишу и примењују транзакционо.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Додато у омиљене")
}
}
PhotoKit пружа механизам посматрања промена у медијатеци кроз протокол PHPhotoLibraryChangeObserver. При било каквим променама (креирање, брисање, уређивање) позива се метода photoLibraryDidChange са PHChange објектом.
PHChange садржи changeDetails за сваки тип упита: PHFetchResultChangeDetails са removedIndexes, insertedIndexes, changedIndexes. Ово омогућава примену промена у UI-ју са анимацијом: performBatchUpdates са move, insert, delete за 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
// Примени измене на collectionView
}
}
}
PhotoKit подржава уређивање медија кроз механизам PHContentEditingInput и PHContentEditingOutput. Апликација захтева editingInput са оригиналним подацима, примењује измене и чува резултат кроз editingOutput. Фрејмворк аутоматски чува оригинал, омогућавајући кориснику да врати измене ресетовањем на оригинал.
RAW фотографије (DNG, CR2, NEF) су подржане кроз PHAssetResourceManager, који пружа приступ оригиналној RAW датотеци. За обраду RAW-а препоручује се коришћење CoreImage-а са CIRAWFilter филтером, који подржава подешавање температуре, експозиције и оштрине. PhotoKit такође подржава проширења уређивача кроз Photo Editing Extension (iOS) — апликација може бити позвана из системског уређивача за обраду изабране фотографије или видеа.
PhotoKit — моћан, али ресурсно захтеван фрејмворк. Неправилна употреба може довести до успорења при скроловању и прекомерне потрошње меморије. Пратите препоруке за оптималне перформансе.
PHLivePhoto — захтева засебан упит кроз PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Не захтевајте Live Photo за ћелије где се приказује само фотографија — користите PHLivePhotoBadge за индикацију.
Често постављана питања
PhotoKit — савремени Apple фрејмворк за рад са медијатеком, представљен у iOS 8. За разлику од застарелог AssetsLibrary-а, PhotoKit пружа објектни модел PHAsset, PHFetchResult са брзим претраживањем, подршку за iCloud и Change Tracking за посматрање промена.
Позовите PHPhotoLibrary.requestAuthorization(for: .readWrite) са обрадом у callback-у. Након добијања статуса .authorized можете извршавати упите PHAsset.fetchAssets. За писање је потребан приступ .readWrite. Само за читање — .addOnly.
Користите PHImageManager.default().requestImage са параметрима: asset, targetSize, contentMode и PHImageRequestOptions. Асинхрони метод враћа PHImageRequestID, омогућавајући отказивање упита. За колекције користите PHCachingImageManager са предучитавањем.
Региструјте посматрача кроз PHPhotoLibrary.shared().register(self) и имплементирајте протокол PHPhotoLibraryChangeObserver. У методи photoLibraryDidChange добићете PHChange са changeDetails за сваки fetchResult и примените промене у UI-ју са анимацијом.
У PHImageRequestOptions поставите isNetworkAccessAllowed = true и progressHandler за праћење учитавања из iCloud-а. При брзом скроловању искључите мрежни приступ и учитавајте само локалне верзије да бисте избегли кашњења при скроловању.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође