简体   繁体   English

快速检测照片库中已删除的图像

[英]detect deleted image from photo gallery in swift

I am saving local identifiers of PHAssets of photo gallery images and showing those images in collection view. 我要保存PHAssets图片库图像的本地标识符,并在集合视图中显示这些图像。 My problem is that when I delete image from photo library then my app crashes as it is not able to fetch the PHAsset that has been deleted from the photo library. 我的问题是,当我从照片库中删除图像时,我的应用程序崩溃,因为它无法获取从照片库中删除的PHAsset。 Here is my code to show the assets: 这是显示资产的代码:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = photoCollectionView.dequeueReusableCell(withReuseIdentifier: "imageShowCell", for: indexPath) as! imageShowCell
     let image = photoArray.object(at: indexPath.item) as! Photos
     let imageManager = PHImageManager()
     let asset = PHAsset.fetchAssets(withLocalIdentifiers: [image.pic_name!], options: nil)[0]
    let scale  = UIScreen.main.scale
    let size = CGSize(width: 50.0 * scale, height: 50.0 * scale)
    imageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: nil) { (image, _) in
        cell.imageView.image  = image
    }
    return cell
}

You need to register a change observer with the photo library. 您需要在照片库中注册更改观察者。 You'll then get told when photos are deleted, inserted, changed or moved. 然后会告诉您何时删除,插入,更改或移动照片。 The observer needs to inherit from PHPhotoLibraryChangeObserver . 观察者需要从PHPhotoLibraryChangeObserver继承。 You then need to implement the function photoLibraryDidChange(_ changeInstance: PHChange) . 然后,您需要实现功能photoLibraryDidChange(_ changeInstance: PHChange) If you use your view controller as the observer you should be able to catch all changes in the collection view as follows. 如果将视图控制器用作观察者,则应该能够按以下方式捕获集合视图中的所有更改。 The example below assumes you have an array of all the phAssets your collection view needs to displays its images readily available 下面的示例假定您有一个集合,其中包含所有phAsset,您的集合视图需要显示随时可用的图像

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!
}

Currently you are creating you PHAsset temporarily. 当前,您正在临时创建PHAsset。 You need a permanent PHObject of some form for the above function to be of any use. 您需要某种形式的永久性PHObject才能使上述功能有用。 If you store individual PHAssets in your photoArray object you can use PHChange.changeDetails(for object: PHObject) on each of these to catch whether they have been deleted while the app was running. 如果将单个PHAsset存储在photoArray对象中,则可以在每个PHChange.changeDetails(for object: PHObject)上使用PHChange.changeDetails(for object: PHObject) ,以捕获应用程序运行时是否已将其删除。 This won't work between sessions of the app though. 不过,这在应用程序的会话之间将无法正常工作。

Instead of storing an array of local identifiers you could create an Album and store all the images your app uses in that Album. 您可以创建相册并将应用程序使用的所有图像存储在该相册中,而不是存储本地标识符数组。 Then you can watch for changes to that Album. 然后,您可以查看对该相册的更改。

As an aside the reason you are getting a crash is you are asking for array element [0] of an empty array. 另外,导致崩溃的原因是您要查询空数组的数组元素[0]。 You can avoid the crash by checking the result of your PHAsset.fetchAssets() call has a count greater than zero. 您可以通过检查PHAsset.fetchAssets()调用的结果计数是否大于零来避免崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM