iOS: Робота з галереєю (Photos framework). Частина 2

Привіт, Хабр! У цій статті я розповім про роботу з відео, live-фото і відстеження змін в галереї за допомогою Photos framework. Для кращого розуміння статті рекомендую ознайомитися з попередньою статтею.


Робота з відео
Для того, щоб завантажити відео з галереї необхідно задати параметри(опції) запиту — PHVideoRequestOptions.
let options = PHVideoRequestOptions()
// Вказуємо, що PHImageManager може завантажувати відео з iCloud
options.isNetworkAccessAllowed = true
// Обираємо автоматичне якість відео
options.deliveryMode = .automatic
options.progressHandler = { progress, _, _, _ in
// Тут можна відобразити поточний прогрес завантаження
}

Далі ці параметри разом з об'єктом PHAsset(див. попередню статтю) передаємо в наступну функцію:
PHImageManager.default().requestPlayerItem(forVideo: asset, 
options: options, 
resultHandler: { playerItem, info in
// Можемо використовувати об'єкт playerItem
}

Після того як отримали playerItem, можна її відтворити. Для програвання відео використовується клас AVPlayerLayer і AVPlayer:
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)

// Конфігуруємо playerLayer і додаємо його в view

player.play() 


Робота з live-фото
Робота з live-фото та відео схожі. Для початку ми задаємо параметри запиту, тільки тепер з допомогою класу PHLivePhotoRequestOptions:
let options = PHLivePhotoRequestOptions()
options.isNetworkAccessAllowed = true
options.deliveryMode = .highQualityFormat
options.progressHandler = { progress, _, _, _ in
// Тут можна відобразити поточний прогрес завантаження
}

Потім завантажуємо live-фото:
PHImageManager.default().requestLivePhoto(for: asset, 
targetSize: targetSize,
contentMode: .aspectFit,
options: options,
resultHandler: { livePhoto, info in
// Можемо використовувати об'єкт livePhoto
})

Після отримання об'єкта livePhoto можемо відобразити його в спеціальному компоненті PHLivePhotoView. Цей компонент дуже схожий на UIImageView. Він призначений для відображення live-фото.
livePhotoView.livePhoto = livePhoto

// Показуємо live-фото
livePhotoView.startPlayback(with: .full)


Відстеження змін в галереї
Photos framework дозволяє стежити за змінами, які відбулися як з альбомами так і з окремими фото або відео. Щоб почати відстежувати зміни потрібно додати обсервер в PHPhotoLibrary:
PHPhotoLibrary.shared().register(observer)

Обсервер повинен реалізовувати протокол PHPhotoLibraryChangeObserver, в якому є всього один метод — photoLibraryDidChange(_ changeInstance: PHChange). Параметр changeInstance — це об'єкт, який містить перелік змін, що відбулися в галереї.
В якості прикладу покажу як оновити collectionView у відповідності з змінами, що відбулися.
func photoLibraryDidChange(_ changeInstance: PHChange) {
// Отримуємо зміни списку PHAsset (змінна fetchResult)
// Якщо змін не було, то виходимо з функції
guard let changes = changeInstance.changeDetails(for: fetchResult) else { return }

// Повідомлення могло прийти не з main queue, тому перестраховуємося
DispatchQueue.main.sync {
// Присвоюємо новий список PHAsset
fetchResult = changes.fetchResultAfterChanges
// Перевіряємо, чи можна отримати список змін за групами
// (видалені, додані, змінені, переміщені)
if changes.hasIncrementalChanges {
// Анимируем зміни в collectionView
collectionView.performBatchUpdates({
// Тут важливо дотримати порядок змін:
// delete, insert, reload, move
if let removed = changes.removedIndexes where removed.count > 0 {
collectionView.deleteItems(at: removed.map { IndexPath(item: $0, section:0) })
}
if let inserted = changes.insertedIndexes where inserted.count > 0 {
collectionView.insertItems(at: inserted.map { IndexPath(item: $0, section:0) })
}
if let changed = changes.changedIndexes where changed.count > 0 {
collectionView.reloadItems(at: changed.map { IndexPath(item: $0, section:0) })
}
changes.enumerateMoves { fromIndex, toIndex in
collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
to: IndexPath(item: toIndex, section: 0))
}
})
} else {
// Просто перезавантажуємо collectionView
collectionView.reloadData()
}
}
}


Висновок
Наведений в статтях код не є ідеальним. Головне його завдання — показати механізм роботи Photos framework. Якщо щось незрозуміло — запитуйте в коментарях. Можливо, трохи пізніше зроблю на github репозиторій з проектом, де зберу весь код разом.
Спасибі за прочитання.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.