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

时间:2018-12-10 17:22:33

标签: ios swift photo phimagemanager

我正在保存相册图像的PHAsset的本地标识符,并显示这些标识符  集合视图中的图像。我的问题是,当我从照片库中删除图像时  然后我的应用程序崩溃,因为它无法获取已删除的PHAsset  从照片库。这是我显示资产的代码:

 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
}

1 个答案:

答案 0 :(得分:0)

您需要在照片库中注册更改观察者。然后会告诉您何时删除,插入,更改或移动照片。观察者需要从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才能使上述功能有用。如果将单个PHAsset存储在photoArray对象中,则可以在其中每个上使用PHChange.changeDetails(for object: PHObject)来捕获应用程序运行时是否已将其删除。不过,这在应用程序的两次会话之间将无法正常工作。

您可以创建相册并将应用程序使用的所有图像存储在该相册中,而不是存储本地标识符数组。然后,您可以监视该相册的更改。

顺便说一句,您崩溃的原因是您要查询空数组的数组元素[0]。您可以通过检查PHAsset.fetchAssets()调用的结果计数是否大于零来避免崩溃。