Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHImageManager.requestImageForAsset returns nil when creating thumbnail for video

Tags:

ios

swift

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]
like image 946
Andreas Du Rietz Avatar asked Feb 06 '15 15:02

Andreas Du Rietz


1 Answers

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.

like image 195
Rick Roberts Avatar answered Oct 14 '22 21:10

Rick Roberts