Sunday, July 30, 2017

List all gif files in photo library

Leave a Comment

I have a requirement in which the user needs to fetch a gif from a list of gif files in library. I tried to fetch both images & Videos without any issue. But when I used kUTTypeGIF as media, it crashes with error :

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No available types for source 0'

Here is my code:

#import "ViewController.h" #import <MobileCoreServices/MobileCoreServices.h>  @interface ViewController ()<UIImagePickerControllerDelegate, UINavigationControllerDelegate>  @end  @implementation ViewController  - (void)viewDidLoad {     [super viewDidLoad]; }  -(IBAction)btnChooseGif:(id)sender {     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];     imagePicker.delegate = self;     imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;     imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeGIF, nil];   // Here is the crash      [self presentViewController:imagePicker animated:YES completion:nil]; }  -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {  } @end 

How can i solve this? And if kUTTypeGIF media is not supported here, how can i show the list all gif files to the user for choosing one? I need to display gif files only in the UIImagePickerController

2 Answers

Answers 1

iOS does not give you an easy way to determine -- while using UIImagePickerController -- what the underlying file format is for the pictures stored in the camera roll. Apple's philosophy here is that an image should be thought of as a UIImage object and that you should not care what the ultimate file format is.

So, since you can not use UIImagePickerController to filter out GIF files. Here's a couple possibilities for you:

1 )

Once you pick an image, you can determine what kind of file it is. Here's an example question that asks how to determine if the image is a PNG or JPEG. Once the user picks a file, you'll know whether it's a GIF or a JPEG or a PNG or whatever.

2 )

You could convert any UIImage to a GIF file. Here's a question that points to a library that might be able to help.

3 )

You could iterate across the entire camera roll and convert/save those images into your app's documents directory as GIF files. Something that starts with enumeration found in this related question and then runs each picture through the ImageIO framework to convert it to a gif file (the code for which I pointed out in solution # 2). You can then roll your own picker.

p.s. your own code wasn't going to work because, as Nathan pointed out, gif is not a media type. This is a function that points out the available media types:

-(IBAction)btnChooseGif:(id)sender {     NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypePhotoLibrary];      NSLog(@"availableMedia is %@", availableMedia);      UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];     imagePicker.delegate = self;     imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;      imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeImage, nil];     [self presentViewController:imagePicker animated:YES completion:nil]; } 

Answers 2

If you only want to fetch assets from Photos library without picker, you can use PHFetchResult for getting array of PHAsset. Below is the list of available MediaType enums available in Photos.Framework:

typedef NS_ENUM(NSInteger, PHAssetMediaType) { PHAssetMediaTypeUnknown = 0, PHAssetMediaTypeImage   = 1, PHAssetMediaTypeVideo   = 2, PHAssetMediaTypeAudio   = 3, } PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0); 

You can use it as :

PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil]; 

and request image from asset as :

PHImageManager *manager = [PHImageManager defaultManager];      PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];     requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;     requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;     requestOptions.synchronous = true;  [manager requestImageDataForAsset:asset options:requestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {  NSLog(@"Data UTI :%@ \t Info :%@",dataUTI,info);             }]; 

Hope this will help you!!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment