I am trying to fetch all photos from my device, and show them in a collection:
var allPhotos : PHFetchResult<PHAsset>? = nil
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .authorized:
let fetchOptions = PHFetchOptions()
self.allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
print("Found \(allPhotos.count) assets")
case .denied, .restricted:
print("Not allowed")
case .notDetermined:
// Should not see this when requesting
print("Not determined yet")
}
}
This code fetches all the photos from the device and as well as from iCloud and then stores them into allPhotos
array. But when I am trying to set them using this function in collection view cell, I am only getting photos from the device. The other photos cell is empty. Converting images with this function:
func getUIImage(asset: PHAsset) -> UIImage? {
var img: UIImage?
let manager = PHImageManager.default()
let options = PHImageRequestOptions()
options.version = .original
options.isSynchronous = true
manager.requestImageData(for: asset, options: options) { data, _, _, _ in
if let data = data {
img = UIImage(data: data)
}
}
return img
}
And for some images I am getting this error "Failed to load image data for asset " for those empty cells. Can someone explain why it is not fetching iCloud images?
Because the following code is a closure.
manager.requestImageData(for: asset, options: options) { data, _, _, _ in
if let data = data {
img = UIImage(data: data)
}
}
And closures execute on background thread and are not inline. Closure execution may take time and might not return data instantaneously.
What you could try is creating a closure callback for image to load.
func getUIImage(asset: PHAsset, complition : @escaping ((_ img:UIImage?,_ error:String?) -> Void)){
let manager = PHImageManager.default()
let options = PHImageRequestOptions()
options.version = .original
options.isSynchronous = true
manager.requestImageData(for: asset, options: options) { data, _, _, _ in
if let data = data,
let img = UIImage(data: data){
complition(img,nil)
}else{
complition(nil,"Something went wrong")
}
}
}
You can try this. Hope this help.