Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all gif files in photo library

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

like image 310
Amal T S Avatar asked Jul 21 '17 07:07

Amal T S


3 Answers

In iOS 11 you can get all gif by Smart Album.

func getGif() -> PHFetchResult<PHAsset> {
     if let gifCollection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumAnimated, options: nil).firstObject {
        return PHAsset.fetchAssets(in: gifCollection, options: nil)
    }
    return PHFetchResult<PHAsset>()
}
like image 133
PowHu Avatar answered Sep 25 '22 14:09

PowHu


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!!

like image 32
Anand Kore Avatar answered Sep 24 '22 14:09

Anand Kore


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];
}
like image 44
Michael Dautermann Avatar answered Sep 23 '22 14:09

Michael Dautermann