iosarraysphasset

PHFetchRequest returns nil data mixed with optional data for images?


I am learning how to use the PHFetchRequest to get images from the user's photo library and then display them in a scroll view for a custom image picker but I am getting mostly nil returned data and some returned as optional data that can be un-wrapped.

I back up all my photos on ICloud, could this be the reason I am getting nil??

Below is the function within my struct that fetches and appends the data to an empty array variable...

What am I doing wrong? Thanks guys!

XCode log showing nil and optional returns

   func getAllImages() {
        let request = PHAsset.fetchAssets(with: .image, options: .none)
        
        DispatchQueue.global(qos: .background).async {
            let options = PHImageRequestOptions()
            options.isSynchronous = true
            
            request.enumerateObjects { (asset, _, _ ) in
                PHCachingImageManager.default().requestImage(for: asset, targetSize: .init(), contentMode: .default, options: options) { (image, _) in
                    print(image?.pngData())

                    // I had to coalesce with an empty UIImage I made as an extension
                    let data1 = Images(image: (image ?? UIImage.emptyImage(with: CGSize(width: 10, height: 10)))!, selected: false)
                    self.data.append(data1)
                }
            }
            
            if request.count == self.data.count {
                self.getGrid()
            }
            
        }
    }


Solution

  • You are seeing nil data because the image resource is in cloud and not on your phone. Optional is expected because it is not guaranteed to exist on your phone (like it's in cloud in your case).

    You can instruct fetch request to fetch the photo from cloud (if needed) using PHImageRequestOptions.isNetworkAccessAllowed option. This is false by default.

    A Boolean value that specifies whether Photos can download the requested image from iCloud.

    Discussion

    If true, and the requested image is not stored on the local device, Photos downloads the image from iCloud. To be notified of the download’s progress, use the progressHandler property to provide a block that Photos calls periodically while downloading the image.

    If false (the default), and the image is not on the local device, the PHImageResultIsInCloudKey value in the result handler’s info dictionary indicates that the image is not available unless you enable network access.

    progressHandler Notes

    You don't need to implement this to allow iCloud photo downloads. The iCloud photo downloads will work without this as well. In case you plan to implement this to show progress on UI, you should keep in mind that these calls are fired multiple times for one download. So you can't consider your photo download to be complete upon first call in progressHandler callback.

    Discussion

    If you request an image whose data is not on the local device, and you have enabled downloading with the isNetworkAccessAllowed property, Photos calls your block periodically to report progress and to allow you to cancel the download.