如何在 Swift 3 中正确获取所有照片 iOS(为什么我得到重复的照片)

How to get all photos properly in Swift3 iOS(Why I get duplicated photos)

我想列出来自 "My Photo Stream" 的所有照片,这是我的代码:

private func fetchAssetCollection(){
    let result = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumMyPhotoStream, options: nil)
    result.enumerateObjects({ (collection, index, stop) in
        if let albumName = collection.localizedTitle {
            print("Album => \(collection.localIdentifier), \(collection.estimatedAssetCount), \(albumName) ")
        }

        let assResult = PHAsset.fetchAssets(in: collection, options: nil)

        let options = PHImageRequestOptions()
        options.resizeMode = .exact
        let scale = UIScreen.main.scale
        let dimension = CGFloat(78.0)
        let size = CGSize(width: dimension * scale, height: dimension * scale)

        assResult.enumerateObjects({ (asset, index, stop) in
            print("index \(index)")
            PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: options) { (image, info) in
                if let name = asset.originalFilename {
                    print("photo \(name) \(index) \(asset.localIdentifier)")
                }
            }

        })

    })
}



extension PHAsset {

var originalFilename: String? {

    var fname:String?

    if #available(iOS 9.0, *) {
        let resources = PHAssetResource.assetResources(for: self)
        if let resource = resources.first {
            fname = resource.originalFilename
        }
    }

    if fname == nil {
        // this is an undocumented workaround that works as of iOS 9.1
        fname = self.value(forKey: "filename") as? String
    }

    return fname
}

}

它可以工作,但问题是它打印了重复的记录。 它打印 329*2 条记录,但实际上我的 "My Photo stream" 中有 329 张照片。

photo IMG_0035.JPG 10 0671E1F3-CB7C-459E-8111-FCB381175F29/L0/001
photo IMG_0035.JPG 10 0671E1F3-CB7C-459E-8111-FCB381175F29/L0/001
......

来自 PHImageManager requestImage 的文档:

By default, this method executes asynchronously. If you call it from a background thread you may change the isSynchronous property of the options parameter to true to block the calling thread until either the requested image is ready or an error occurs, at which time Photos calls your result handler.

For an asynchronous request, Photos may call your result handler block more than once. Photos first calls the block to provide a low-quality image suitable for displaying temporarily while it prepares a high-quality image. (If low-quality image data is immediately available, the first call may occur before the method returns.) When the high-quality image is ready, Photos calls your result handler again to provide it. If the image manager has already cached the requested image at full quality, Photos calls your result handler only once. The PHImageResultIsDegradedKey key in the result handler’s info parameter indicates when Photos is providing a temporary low-quality image.

因此,要么使请求同步,要么检查 info 字典中的 PHImageResultIsDegradedKey 值,以查看该图像实例是否是您真正希望保留或忽略的那个。