2017-07-21 54 views
8

我有一個要求,用戶需要從庫中的gif文件列表中獲取gif。我試圖獲取兩個圖像&視頻沒有任何問題。但是,當我用kUTTypeGIF作爲媒體,它崩潰,出現錯誤:列出照片庫中的所有gif文件

終止應用程序由於未捕獲的異常 「NSInvalidArgumentException」的,理由是:「無可用類型源 0」

這裏是我的代碼:

#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 

我該如何解決這個問題?如果kUTTypeGIF媒體在這裏不受支持,我如何顯示列表中的所有gif文件給用戶選擇一個?我只需要在UIImagePickerController中顯示gif文件

+0

檢查這個https://stackoverflow.com/questions/37934698/how-to-load-animated-gif-from-photo-library –

+0

@DSDharma那不是我的問題。我希望我的應用程序能夠在圖像選取器中列出所有gif文件。用戶應該只能看到手機中的gif文件供選擇 – Bali

+2

GIF不是有效的媒體類型。允許的媒體類型是「圖像」和「電影」。您可以使用'UIImagePickerController.availableMediaTypes(for:.photoLibrary)'檢查接受的類型。' – nathan

回答

3

iOS不會爲您提供簡單的方法來確定 - 在使用UIImagePickerController時 - 存儲在相機膠捲中的圖片的底層文件格式。蘋果公司的理念是,圖像應該被認爲是一個對象,你不應該在意最終的文件格式是什麼。

所以,因爲你不能使用UIImagePickerController過濾掉GIF文件。這裏有一對夫婦的可能性,您:

1)

一旦你選擇一個圖片,你能確定它是什麼類型的文件。 Here's an example question that asks how to determine if the image is a PNG or JPEG。一旦用戶選擇一個文件,你就會知道它是一個GIF還是一個JPEG或一個PNG或其他什麼。

2)

你可以轉換任何的UIImage到GIF文件。 Here's a question that points to a library that might be able to help

3)

你可以在整個相機膠捲遍歷和轉換/這些圖片到你的應用程序的文件目錄保存爲GIF文件。首先啓動with enumeration found in this related question,然後通過ImageIO框架運行每個圖片,將其轉換爲gif文件(我在解決方案#2中指出的代碼)。然後你可以推出你自己的選擇器。

p.s.你自己的代碼不會起作用,因爲,正如Nathan指出的,gif不是媒體類型。這是指出了可用的介質類型的函數:

-(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]; 
} 
3

如果你只是想不選擇器來從照片庫中的資產,您可以使用PHFetchResult用於獲取的PHAsset陣列。以下是可用的MediaType enums可用列表中Photos.Framework

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

你可以使用它作爲:

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

,並要求圖像從資產爲:

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); 
      }]; 

希望這將幫助你!

1

在iOS 11中,您可以通過智能相冊獲取所有gif。

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>() 
}