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()
}
}
}
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.
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.