Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHCachingImageManager.requestImage is always called twice?

I have a UICollectionView with a custom UICollectionViewCell that should get and display thumbnail (low quality) photos from the Photo (usually the user can select more than 1 photo) in each UIImageView in the cell.

I've been playing with the PHImageRequestOptions and their properties, reading about them. To a point that I even passed nil as a parameter for requestImage(for: PHAsset) method because I'm not sure where I'm wrong.

The problem is that the requestImage(for: PHAsset) method is called twice. I need the first time that it's called to just to set the image in each collection view cell with the low quality (thumbnail image) and once the full size image is ready, it should be added in an image array called assetsTurnedIntoImages. The problem is that I'm doing something wrong and I always get the if and the else method called twice, so basically, if I've selected 4 images from the Camera Roll (hence, I have 4 images in the assets array) and when they go through the requestImage(for: asset) method I get 8 images in the assetsTurnedIntoImages instead of 4. So Here's my code

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        print("Assets count is:", assets.count)
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoPostCVCell", for: indexPath) as! PhotoPostCVCell
        if let takenImage = cameraPhotoUIImage
        {
            cell.cellImage.image = takenImage
        }
        if assets.count > 0
        {
            let asset = assets[indexPath.row]

//            var imageRequestOptions: PHImageRequestOptions
//            {
//                let options = PHImageRequestOptions()
//                //options.version = .current
//                //options.resizeMode = .exact
//                //options.deliveryMode = .fastFormat
//                options.isSynchronous = true
//                return options
//            }
            let targetSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
            imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil)
            { (image, info) in
                if image != nil
                {
                    let imageQualityState = info![PHImageResultIsDegradedKey] as! Bool

                    if imageQualityState
                    {
                        print("LOW QUALITY")
                        print("Image Quality State is:", imageQualityState)
                        cell.cellImage.image = image
                        print(image!.size)
                    }
                    else
                    {
                        print(image!.size)
                        cell.cellImage.image = image
                        self.assetsTurnedIntoImages.append(image!)
                    }
                }
            }
        }
        return cell
    }
like image 212
Dani Avatar asked Sep 20 '17 14:09

Dani


1 Answers

You can discard those low-res duplicates by including this conditional:

imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil) { (image, info) in

let isDegraded = (info?[PHImageResultIsDegradedKey] as? Bool) ?? false
if isDegraded {
   return
}
like image 165
Manu Avatar answered Oct 01 '22 21:10

Manu