From d84970d2daf763f6a782c010ac9a9987f41d6c05 Mon Sep 17 00:00:00 2001 From: tilltue Date: Sun, 3 Sep 2017 21:56:59 +0900 Subject: [PATCH] add PHPhotoLibraryChangeObserver - Fixes #24 --- .../Classes/TLAssetsCollection.swift | 2 ++ TLPhotoPicker/Classes/TLPhotoLibrary.swift | 13 +++++-- .../TLPhotosPickerViewController.swift | 36 ++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/TLPhotoPicker/Classes/TLAssetsCollection.swift b/TLPhotoPicker/Classes/TLAssetsCollection.swift index 36c8b7aa..394c4429 100644 --- a/TLPhotoPicker/Classes/TLAssetsCollection.swift +++ b/TLPhotoPicker/Classes/TLAssetsCollection.swift @@ -59,6 +59,7 @@ extension TLPHAsset: Equatable { } struct TLAssetsCollection { + var phAssetCollection: PHAssetCollection? = nil var fetchResult: PHFetchResult? = nil var thumbnail: UIImage? = nil var useCameraButton: Bool = false @@ -73,6 +74,7 @@ struct TLAssetsCollection { } init(collection: PHAssetCollection) { + self.phAssetCollection = collection self.title = collection.localizedTitle ?? "" self.localIdentifier = collection.localIdentifier } diff --git a/TLPhotoPicker/Classes/TLPhotoLibrary.swift b/TLPhotoPicker/Classes/TLPhotoLibrary.swift index fbc47579..eb01bd47 100644 --- a/TLPhotoPicker/Classes/TLPhotoLibrary.swift +++ b/TLPhotoPicker/Classes/TLPhotoLibrary.swift @@ -111,11 +111,20 @@ class TLPhotoLibrary { //MARK: - Load Collection extension TLPhotoLibrary { - func fetchCollection(allowedVideo: Bool = true, useCameraButton: Bool = true, mediaType: PHAssetMediaType? = nil) { - + func getOption() -> PHFetchOptions { let options = PHFetchOptions() let sortOrder = [NSSortDescriptor(key: "creationDate", ascending: false)] options.sortDescriptors = sortOrder + return options + } + + func fetchResult(collection: TLAssetsCollection?) -> PHFetchResult? { + guard let phAssetCollection = collection?.phAssetCollection else { return nil } + return PHAsset.fetchAssets(in: phAssetCollection, options: getOption()) + } + + func fetchCollection(allowedVideo: Bool = true, useCameraButton: Bool = true, mediaType: PHAssetMediaType? = nil) { + let options = getOption() @discardableResult func getSmartAlbum(subType: PHAssetCollectionSubtype, result: inout [TLAssetsCollection]) -> TLAssetsCollection? { diff --git a/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift b/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift index 61054b98..bd3ac64d 100644 --- a/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift +++ b/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift @@ -121,6 +121,7 @@ open class TLPhotosPickerViewController: UIViewController { deinit { //print("deinit TLPhotosPickerViewController") + PHPhotoLibrary.shared().unregisterChangeObserver(self) } required public init?(coder aDecoder: NSCoder) { @@ -267,6 +268,10 @@ extension TLPhotosPickerViewController { } } + fileprivate func registerChangeObserver() { + PHPhotoLibrary.shared().register(self) + } + fileprivate func getfocusedIndex() -> Int { guard let focused = self.focusedCollection, let result = self.collections.index(where: { $0 == focused }) else { return 0 } return result @@ -398,6 +403,7 @@ extension TLPhotosPickerViewController: TLPhotoLibraryDelegate { func loadCompleteAllCollection(collections: [TLAssetsCollection]) { self.collections = collections self.reloadTableView() + self.registerChangeObserver() } func focusCollection(collection: TLAssetsCollection) { @@ -523,8 +529,36 @@ extension TLPhotosPickerViewController: PHLivePhotoViewDelegate { } } +// MARK: - PHPhotoLibraryChangeObserver +extension TLPhotosPickerViewController: PHPhotoLibraryChangeObserver { + public func photoLibraryDidChange(_ changeInstance: PHChange) { + guard let changeFetchResult = self.focusedCollection?.fetchResult else { return } + guard let changes = changeInstance.changeDetails(for: changeFetchResult) else { return } + guard let fetchResult = self.photoLibrary.fetchResult(collection: self.focusedCollection) else { return } + let addIndex = self.usedCameraButton ? 1 : 0 + DispatchQueue.main.sync { + if changes.hasIncrementalChanges { + self.collectionView.performBatchUpdates({ [weak self] _ in + self?.focusedCollection?.fetchResult = fetchResult + if let removed = changes.removedIndexes, removed.count > 0 { + self?.collectionView.deleteItems(at: removed.map { IndexPath(item: $0+addIndex, section:0) }) + } + if let inserted = changes.insertedIndexes, inserted.count > 0 { + self?.collectionView.insertItems(at: inserted.map { IndexPath(item: $0+addIndex, section:0) }) + } + if let changed = changes.changedIndexes, changed.count > 0 { + self?.collectionView.reloadItems(at: changed.map { IndexPath(item: $0+addIndex, section:0) }) + } + }) + }else { + self.focusedCollection?.fetchResult = fetchResult + self.collectionView.reloadData() + } + } + } +} -// UICollectionView delegate & datasource +// MARK: - UICollectionView delegate & datasource extension TLPhotosPickerViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDataSourcePrefetching { fileprivate func getSelectedAssets(_ asset: TLPHAsset) -> TLPHAsset? { if let index = self.selectedAssets.index(where: { $0.phAsset == asset.phAsset }) {