15

I have no idea why this is so difficult. I'm trying to determine the file type of a PHAsset, specifically, I want to know if a given asset represents a GIF image or not.

Simply inspecting the asset's filename tells me it's an MP4:

[asset valueForKey:@"filename"] ==> "IMG_XXXX.MP4"

Does iOS convert GIF's to videos when saved to the devices image library? I've also tried fetching the image's data and looking at it's dataUTI, but it just returns nil for GIF's (I'm assuming all videos as well). I'm fetching the image data as follows:

PHImageManager *manager = asset.imageManager ? asset.imageManager : [PHImageManager defaultManager];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    PHImageRequestOptions *o = [[PHImageRequestOptions alloc] init];
    o.networkAccessAllowed = YES;

    [manager requestImageDataForAsset:asset.asset options:o resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {

        dispatch_async(dispatch_get_main_queue(), ^{
            CIImage *ciImage = [CIImage imageWithData:imageData];
            if(completion) completion(imageData, dataUTI, orientation, info, ciImage.properties);
        });

    }];

});

the dataUTI returned from the above call is nil.

If anyone knows of a reliable way to determine a PHAsset's file type (I'm specifically looking for GIF's, but being able to determine for any type of file would be great) let me know!

Cœur
  • 37,241
  • 25
  • 195
  • 267
mitchtreece
  • 181
  • 1
  • 2
  • 7

6 Answers6

15

Use PHAssetResource.

    NSArray *resourceList = [PHAssetResource assetResourcesForAsset:asset];
    [resourceList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PHAssetResource *resource = obj;
        if ([resource.uniformTypeIdentifier isEqualToString:@"com.compuserve.gif"]) {
           isGIFImage = YES;
        }
    }];
dongkang
  • 201
  • 2
  • 4
6

Also you can find uniformTypeIdentifier from PHContentEditingInput class. For this; use requestContentEditingInput function from PHAsset

Don't forget to import MobileCoreServices for kUTTypeGif

Sample Swift 3.1 code:

    let options = PHContentEditingInputRequestOptions()
    options.isNetworkAccessAllowed = true //for icloud backup assets

    let asset : PHAsset = .....  //sampleAsset
    asset.requestContentEditingInput(with: options) { (contentEditingInput, info) in
        if let uniformTypeIdentifier = contentEditingInput?.uniformTypeIdentifier {

            if uniformTypeIdentifier == (kUTTypeGIF as String) {
                debugPrint("This asset is a GIF")
            }

        }
    }
sirman
  • 99
  • 2
  • 4
  • 2
    This doesn't seem to work from a **Photos.app Editing Extension**. I am only passed the `PHContentEditingInput` at the beginning of the session (not the asset itself), and the property `uniformTypeIdentifier` is `nil`... – Nicolas Miari Feb 03 '19 at 13:58
  • This seems a bit heavy-handed because this function requests the actual image / video and prepares it for editing. And it's asynchronous, which indicates it takes some time / resources to perform. – Frederic Adda Apr 21 '20 at 11:48
5

For Swift 3.0 and above

import MobileCoreServices


var isGIFImage = false
if let identifier = asset.value(forKey: "uniformTypeIdentifier") as? String
{
  if identifier == kUTTypeGIF as String
  {
    isGIFImage = true
  }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Hiren Panchal
  • 2,963
  • 1
  • 25
  • 21
3

I guess since iOS 11, we can use:

if asset.playbackStyle == .imageAnimated {
    // try to show gif animation
}
snakehnb
  • 63
  • 7
2

First of all, I am not sure what do you mean by the GIF image.
Are you referring to Live Photo or Time-lapse ?

However, if you want to check the current asset is Live Photo, Time-lapse, then you can check like this

if(asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive)
{
     // this is a Live Photo
}

if(asset.mediaSubtypes == PHAssetMediaSubtypeVideoTimelapse)
{
     // this is a Time-lapse
}

for determining the generic file type of a PHAsset, you can check

   asset.mediaType == PHAssetMediaTypeImage 
   asset.mediaType == PHAssetMediaTypeVideo
   asset.mediaType == PHAssetMediaTypeAudio
papsic
  • 21
  • 2
  • 6
    He means images that are in a .gif format (animated images), not Live Photos or Time-lapses. .png, .jpg, .gif, .tiff are all types of images. Photos on iOS can store gifs, he's asking how you detect if an image is a gif or not. – Kane Cheshire Jun 16 '16 at 20:01
1
//phAsset if object of phAsset

if let imageType = phAsset.value(forKey: "uniformTypeIdentifier") as? String {
    if imageType == kUTTypeGIF as String { 
        //enter code here
    }
}
Manish Patel
  • 117
  • 2
  • 9