Determine if image picker media type is video

nevan king picture nevan king · Mar 25, 2013 · Viewed 7.2k times · Source

I've seen various methods for checking whether the returned media type in -imagePickerController:didFinishPickingMediaWithInfo: is video. For example, my way:

- (void)imagePickerController:(UIImagePickerController *)imagePicker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    if (UTTypeEqual(kUTTypeMovie, 
    (__bridge CFStringRef)[info objectForKey:UIImagePickerControllerMediaType])) 
    {
        // ...
    }
}

or

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {

or

if ([mediaType isEqualToString:(NSString *)kUTTypeVideo] || 
    [mediaType isEqualToString:(NSString *)kUTTypeMovie])

or

if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
        == kCFCompareEqualTo) 

or

if ([mediaType isEqualToString:@"public.movie"]

Everyone seems to have a different way of doing this. What's the recommended method for checking the media type? Preferably with a way to include "all image types" or "all video types".

Answer

Steven Fisher picture Steven Fisher · Mar 31, 2015

It would be better to check for conformance with a particular UTI instead.

Right now, iOS tells you its a public.movie, but what will it say next year? You'll see people checking for public.video as well. Great, so you've hard-coded two types instead of one.

But wouldn't it be better to ask "Is this a movie?" rather than hard code the specific type you think iOS will return? There's a way to do that:

NSString *mediaType = info[UIImagePickerControllerMediaType];
BOOL isMovie = UTTypeConformsTo((__bridge CFStringRef)mediaType,
                                kUTTypeMovie) != 0;

Using this approach, isMovie should be YES if a movie is returned (regardless of which specific type is returned) if mediaType represents a movie, since all movies conform from kUTTypeMovie. To be really clear, if it is a kUTTypeVideo this will also recognize it as a movie, because kUTTypeVideo conforms to kUTTypeMovie.

Likewise, you can check for to see if the thing returned is an image:

NSString *mediaType = info[UIImagePickerControllerMediaType];
BOOL isImage = UTTypeConformsTo((__bridge CFStringRef)mediaType,
                                kUTTypeImage) != 0;

isIamge should be YES if an image is returned, since all images conform to kUTTypeImage.

See Apple's (partial) type tree here: Uniform Type Identifiers Are Declared in a Conformance Hierarchy. You can get a less useful but more complete list of all UTIs currently recognized by your system and their conformance from the shell with:

/System/Library/Frameworks/CoreServices.framework/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump

In particular, you can see public.video is defined like this:

--------------------------------------------------------
type    id:            8344
    uti:           public.video
    description:   video
    flags:         exported  active  core  apple-internal  trusted  
    icon:          
    conforms to:   public.movie
    tags:          
--------------------------------------------------------

Note that UTTypeConformsTo returns true if the types are the same as well. From Apple's docs:

Returns true if the uniform type identifier is equal to or conforms to the second type.