iOS PHImageManager.default().requestImage 回调被同一张图片调用了两次

iOS PHImageManager.default().requestImage callback is called twice for the same image

当我尝试获取具有特定尺寸的图像时,PHImageManager.default().requestImage 被调用两次,并使用不同尺寸的图像。

代码如下:

static func load(from asset: PHAsset, targetSize: CGSize? = nil, completion: @escaping (UIImage?)->()) {
        let options = PHImageRequestOptions()
        options.isSynchronous = false
        let id = UUID()
        PHImageManager.default().requestImage(for: asset, targetSize: targetSize ?? PHImageManagerMaximumSize, contentMode: .aspectFill,
                options: options, resultHandler: { image, _ in
            print(id)
            runInMain {
                completion(image)
            }
        })
    }

我添加了 UUID 以检查是否打印了两次相同的 UUID。

这是因为第一个回调 returns 缩略图是在加载全尺寸图像时。

来自official Apple documentation:

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.

Swift 5 它只调用一次 .deliveryMode = .highQualityFormat

 let manager = PHImageManager.default()
 var imageRequestOptions: PHImageRequestOptions {
        let options = PHImageRequestOptions()
        options.version = .current
        options.resizeMode = .exact
        options.deliveryMode = .highQualityFormat
        options.isNetworkAccessAllowed = true
        options.isSynchronous = true
        return options
    }

  self.manager.requestImage(for: asset,targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: self.imageRequestOptions) { (thumbnail, info) in
         if let img = thumbnail {
             print(img)
          }
    }

使用: requestOptions.deliveryMode = .highQualityFormat

而不是:requestOptions.deliveryMode = .opportunistic

.opportunistic - 照片自动提供一个或多个结果以平衡图像质量和响应能力。