Вам необходимо зарегистрировать наблюдателя изменений в библиотеке фотографий.Затем вам сообщат, когда фотографии будут удалены, вставлены, изменены или перемещены.Наблюдатель должен унаследовать от PHPhotoLibraryChangeObserver
.Затем вам нужно реализовать функцию photoLibraryDidChange(_ changeInstance: PHChange)
.Если вы используете свой контроллер представления в качестве наблюдателя, вы сможете отслеживать все изменения в представлении сбора следующим образом.В приведенном ниже примере предполагается, что у вас есть массив всех наборов phAssets, необходимых для представления вашей коллекции, для быстрого отображения его изображений
class MyViewController : UIViewController, PHPhotoLibraryChangeObserver {
func viewDidLoad() {
...
PHPhotoLibrary.shared().register(self)
...
}
func photoLibraryDidChange(_ changeInstance: PHChange) {
// Change notifications may be made on a background queue.
// Re-dispatch to the main queue to update the UI.
// Check for changes to the displayed album itself
// (its existence and metadata, not its member self).
guard let photos = photos else {return}
// Check for changes to the list of assets (insertions, deletions, moves, or updates).
if let changes = changeInstance.changeDetails(for: photos) {
// Keep the new fetch result for future use.
photos = changes.fetchResultAfterChanges
if changes.hasIncrementalChanges {
// If there are incremental diffs, animate them in the collection view.
self.collectionView.performBatchUpdates({
// For indexes to make sense, updates must be in this order:
// delete, insert, reload, move
if let removed = changes.removedIndexes, removed.count > 0 {
print("photoLibraryDidChange: Delete at \(removed.map { IndexPath(item: $0, section:0) })")
self.collectionView.deleteItems(at: removed.map { IndexPath(item: $0, section:0) })
}
if let inserted = changes.insertedIndexes, inserted.count > 0 {
print("photoLibraryDidChange: Insert at \(inserted.map { IndexPath(item: $0, section:0) })")
self.collectionView.insertItems(at: inserted.map { IndexPath(item: $0, section:0) })
}
if var changed = changes.changedIndexes, changed.count > 0 {
print("photoLibraryDidChange: Reload at \(changed.map { IndexPath(item: $0, section:0) })")
// subtract removed indices
if let removed = changes.removedIndexes {
changed.subtract(removed)
}
self.collectionView.reloadItems(at: changed.map { IndexPath(item: $0, section:0) })
}
changes.enumerateMoves { fromIndex, toIndex in
print("photoLibraryDidChange: Move at \(IndexPath(item: fromIndex, section:0)) to \(IndexPath(item: toIndex, section:0 ))")
self.collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0), to: IndexPath(item: toIndex, section: 0))
}
})
} else {
// Reload the collection view if incremental diffs are not available.
...
}
}
}
var photos : PHFetchResult<PHAsset>?
weak var collectionView : UICollectionView!
}
В настоящее время вы временно создаете свой набор PHAsset.Вам нужен постоянный PHObject какой-либо формы, чтобы вышеуказанная функция была полезной.Если вы храните отдельные объекты PHAssets в своем объекте photoArray, вы можете использовать PHChange.changeDetails(for object: PHObject)
для каждого из них, чтобы узнать, были ли они удалены во время работы приложения.Это не будет работать между сеансами приложения.
Вместо хранения массива локальных идентификаторов вы можете создать альбом и сохранить все изображения, которые ваше приложение использует в этом альбоме.Затем вы можете наблюдать за изменениями в этом альбоме.
Кроме того, причина, по которой вы получаете сбой, заключается в том, что вы запрашиваете элемент массива [0] пустого массива.Вы можете избежать сбоя, проверив, что результат вашего PHAsset.fetchAssets()
вызова имеет счетчик больше нуля.