Andreas Du Rietz Andreas Du Rietz - 7 months ago 316
Swift Question

PHImageManager.requestImageForAsset returns nil when creating thumbnail for video

For some videos, the requestImageForAsset completes with a UIImage that's nil. For other videos it works fine and I haven't figured out why yet.

func createThumbnailForVideo(video: PHAsset) -> Future<NSURL> {
let promise = Promise<NSURL>()
let options = PHImageRequestOptions()
options.synchronous = true

imageManager.requestImageForAsset(video, targetSize: CGSizeMake(640, 640), contentMode: .AspectFill, options: options) { (image:UIImage!, info) -> Void in

if image == nil {
println("Error: Couldn't create thumbnail for video")
promise.error(MyErrors.videoThumb())
} else {
if let thumbURL = self.savePhotoAsTemporaryFile(image) {
promise.success(thumbURL)
} else {
promise.error(MyErrors.videoThumb())
}
}
}

return promise.future
}


I also get back the info for the request but I don't know how to interpret the information:

[PHImageResultIsDegradedKey: 0, PHImageResultWantedImageFormatKey: 4037, PHImageResultIsPlaceholderKey: 0, PHImageResultIsInCloudKey: 0, PHImageResultDeliveredImageFormatKey: 9999]

Answer

I was having the same problem today. For me I had to add the option to download the image if necessary. I think the image manager had a thumbnail size version available but since I hadn't allowed it to fetch the actual image from the network it would return nil on the second call back. So to fix this I created a PHImageRequestOptions() object like this:

var options = PHImageRequestOptions()
options.networkAccessAllowed = true

Then send this as a param with your request:

PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: size, contentMode: PHImageContentMode.AspectFill, options: options) { (image, info) -> Void in
    if (image != nil) {
        cell.imageView.image = image
    }
}

Once I did this the second callback image was not nil. I think it is still a good idea to guard against having a nil image so you don't set the image view's image to nil. I don't think you can assume that the image will always be there. Hope this helps!

EDIT: Just to clarify. In my case for each request, the closure would be called twice. The first time the image was not nil and the second time it was. I think this is because a thumbnail sized version was available but the full size was not. It needed network access to fetch the full size image.

Comments