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
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];
}
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!!
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>()
}
Related
I have simple text file generated in my application. The thing is I want to upload this text file on iCloud so that if the user installs app and inputs data he desires and then agin uninstalls this app. Then the next time he installs that app again I want to fetch the text file uploaded the first time he had used the same app.
I am facing a huge problem in integrating iCloud to my app.
I have done much research but didn't got any specific answers.
P.S. = I am not using Core data.
All i want is to upload the text file generated by the app into the iCloud Drive.
Please guide me step by step how can I achieve this. I have my developer account and I have a bit knowledge about the certificates and all. But still if anyone can please guide me how to achieve it.
I JUST WANT TO UPLOAD THE TEXT FILE TO ICLOUD AND RETRIEVE IT AGAIN WHEN THE SAME APP IS INSTALLED AGAIN (EVEN IF THE APP IS GETTING INSTALLED ON OTHER DEVICES).
ViewController.m
#pragma mark - Image Pick
- (IBAction)pickImage:(id)sender {
//select an image
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
self.imageView.image = image;
//SAVE IMAGE IN iCloud
AppDelegate* myAppDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSURL* cloudeImage = [myAppDelegate applicationCloudFolder:#"thePicture"];
NSData* imageDate = UIImagePNGRepresentation(image);
[imageDate writeToURL:cloudeImage atomically:YES];
}
-(void)populateUI
{
AppDelegate* myAppDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSURL* cloudeImageURL = [myAppDelegate applicationCloudFolder:#"thePicture"];
NSData* imageDate = [NSData dataWithContentsOfURL:cloudeImageURL];
UIImage* image = [UIImage imageWithData:imageDate];
if (image) {
self.imageView.image = image;
}
else
{
//download image from iCloud
NSLog(#"Downloading Image...");
[[NSFileManager defaultManager]startDownloadingUbiquitousItemAtURL:cloudeImageURL error:nil];
}
}
- (NSMetadataQuery *)query {
if (!_query) {
_query = [[NSMetadataQuery alloc]init];
NSArray *scopes = #[NSMetadataQueryUbiquitousDocumentsScope];
_query.searchScopes = scopes;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#", NSMetadataItemFSNameKey, #"*"];
_query.predicate = predicate;
if (![_query startQuery]) {
NSLog(#"Query didn't start... for whatever reason");
}
}
return _query;
}
AppDelegate.m
-(NSURL*)applicationCloudFolder:(NSString*)fileName
{
//TEAM ID AND CONTAINER ID
NSString* teamID = #"V58ESG9PLE";
NSString* bundelID =[NSBundle mainBundle].bundleIdentifier;
NSString* containerID = [NSString stringWithFormat:#"%#.%#",teamID,bundelID];
// URL to Cloud Folder
NSURL* cloudeRootURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:containerID];
NSLog(#"cloudeRootURL %#",cloudeRootURL);
NSURL* cloudDocuments = [cloudeRootURL URLByAppendingPathComponent:#"Document"];
//Apend our file name
cloudDocuments = [cloudDocuments URLByAppendingPathComponent:fileName];
return cloudDocuments;
}
Now I am not getting is my data being saved? ,Where is it getting saved? how can I retrieve it?
P.S. I am saving a picture
I'm new to ios, please help me out.
- (IBAction)btn_actionTakePicture:(UIButton *)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
I press the take picture button, and this code runs, the camera comes up and i can take a photo.
- (NSArray *) listFiles {
NSURL *bundleRoot = [[NSBundle mainBundle] bundleURL];
NSFileManager *fm = [NSFileManager defaultManager];
NSArray * dirContents =
[fm contentsOfDirectoryAtURL:bundleRoot
includingPropertiesForKeys:#[]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
return dirContents;
}
This is where I check file contents to see if the photo was taken and saved in the directory, I basically put the returned (NSArray *) in an NSLog to see the list of files and if there are photos there or not, I did not see any saved jpgs.
Where are the files being saved to, I also checked the photo roll, they aren't being saved there either.
The camera app's files are saved to a location on the hard drive that your app cannot read, due to security restrictions.
The API will return the image in RAM and you are responsible for writing it to a file yourself, in a location of the disk that you do have access to.
Have a look at the sample code for UIImagePickerController to see the method your delegate needs to implement to access the image.
Beware the image will be a 32 bit + alpha channel bitmap image with no compression. You probably want to write it to disk as a jpeg image.
can anyone tell me how to extract images from a video? what i ve tried till now is i ve follow these:
Getting iPhone video thumbnails
Getting a thumbnail from a video url or data in iPhone SDK
How do I extract a screenshot from a video in the iPhone SDK?
iPhone Read UIimage (frames) from video with AVFoundation , iphone sdk > 3.0 . Video Thumbnail?
etc. and after that i ve done this:
Source Code:
- (void)viewDidLoad
{
videoPicker = [[UIImagePickerController alloc] init];
[videoPicker setDelegate:self];
videoPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
NSArray *mediaTypesAllowed = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
videoPicker.mediaTypes = mediaTypesAllowed;
videoPicker.view.hidden = YES;
}
-(IBAction)imgPickerController
{
[self presentModalViewController:videoPicker animated:YES];
videoPicker.view.hidden = NO;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// e.g.
NSString *tempFilePath = [(NSURL *)[info valueForKey:UIImagePickerControllerMediaURL] absoluteString];
NSLog(#"didFinishPickingMediaWithInfo: %#",tempFilePath);
// e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp/capture/capturedvideo.MOV
tempFilePath = [tempFilePath substringFromIndex:16];
NSLog(#"didFinishPickingMediaWithInfo: %#",tempFilePath);
NSLog(#"===Try to save video to camera roll.===");
NSLog(#"UIVideoAtPathIsCompatibleWithSavedPhotosAlbum: %#",UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath)? #"YES":#"NO");
// Check if the video file can be saved to camera roll.
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath))
{
// YES. Copy it to the camera roll.
UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, #selector(video:didFinishSavingWithError:contextInfo:),(__bridge_retained void *)tempFilePath );
}
[self dismissModalViewControllerAnimated:YES];
}
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(NSString *)contextInfo
{
NSLog(#"didFinishSavingWithError--videoPath in camera roll:%#",videoPath);
NSLog(#"didFinishSavingWithError--videoPath in temp directory:%#",contextInfo);
// The thumbnail jpg should located in this directory.
NSString *thumbnailDirectory = [[contextInfo stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
// Debug info. list all files in the directory of the video file.
// e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp/capture
NSLog(#"%#",[contextInfo stringByDeletingLastPathComponent]);
NSLog(#"%#",[[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[contextInfo stringByDeletingLastPathComponent] error:nil] description]);
// Debug info. list all files in the parent directory of the video file, i.e. the "~/tmp" directory.
// e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp
NSLog(#"%#",thumbnailDirectory);
NSLog(#"%#",[[[NSFileManager defaultManager] contentsOfDirectoryAtPath:thumbnailDirectory error:nil] description]);
///////////////////
// Find the thumbnail for the video just recorded.
NSString *file,*latestFile;
NSDate *latestDate = [NSDate distantPast];
NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:[[contextInfo stringByDeletingLastPathComponent]stringByDeletingLastPathComponent]];
// Enumerate all files in the ~/tmp directory
while (file = [dirEnum nextObject])
{
// Only check files with jpg extension.
if ([[file pathExtension] isEqualToString: #"jpg"])
{
NSLog(#"***latestDate:%#",latestDate);
NSLog(#"***file name:%#",file);
NSLog(#"***NSFileSize:%#", [[dirEnum fileAttributes] valueForKey:#"NSFileSize"]);
NSLog(#"***NSFileModificationDate:%#", [[dirEnum fileAttributes] valueForKey:#"NSFileModificationDate"]);
// Check if current jpg file is the latest one.
if ([(NSDate *)[[dirEnum fileAttributes] valueForKey:#"NSFileModificationDate"] compare:latestDate] == NSOrderedDescending)
{
latestDate = [[dirEnum fileAttributes] valueForKey:#"NSFileModificationDate"];
latestFile = file;
NSLog(#"***latestFile changed:%#",latestFile);
}
}
}
// The thumbnail path.
latestFile = [NSTemporaryDirectory() stringByAppendingPathComponent:latestFile];
NSLog(#"****** The thumbnail file should be this one:%#",latestFile);
UIImage *img = [[UIImage alloc] initWithContentsOfFile:latestFile];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(150, 150, 100, 100)];
[imgView setImage:img];
imgView.layer.borderWidth = 2.0;
[self.view addSubview:imgView];
// Your code ...
// Your code ...
// Your code ...
}
After doing all this still i dint reached where i want to reach.i dint get images still.I'm stuck now.Pls anyone help me out!!!Thanks :)
Simple way to extract thumbnails from a movie is to use MPMoviePlayerController class and its - thumbnailImageAtTime:timeOption: method.
For example you've got a filepath url:
NSURL *tempFilePathURL = ...;
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL: tempFilePathURL];
UIImage *thumbnail = [player thumbnailImageAtTime:THUMBNAIL_TIME timeOption:MPMovieTimeOptionExact];
[player release];
I used it in my code and it worked.
thumbnailImageAtTime:timeOption is depricated since iOS 7.0.
Here is an alternative
+ (UIImage *)extractFirstFrameFromFilepath:(NSString *)filepath
{
AVURLAsset *movieAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:filepath] options:nil];
AVAssetImageGenerator *assetImageGemerator = [[AVAssetImageGenerator alloc] initWithAsset:movieAsset];
assetImageGemerator.appliesPreferredTrackTransform = YES;
CGImageRef frameRef = [assetImageGemerator copyCGImageAtTime:CMTimeMake(1, 2) actualTime:nil error:nil];
return [[UIImage alloc] initWithCGImage:frameRef];
}
Swift Version
func getThumbOfVideo(fileURL: URL) -> UIImage? {
let movieAsset = AVURLAsset(url: fileURL)
let assetImageGenerator = AVAssetImageGenerator(asset: movieAsset)
assetImageGenerator.appliesPreferredTrackTransform = true
var thumbnail: UIImage?
do {
let cgImage = try assetImageGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1000), actualTime: nil)
thumbnail = UIImage(cgImage: cgImage)
} catch {
print(error)
}
return thumbnail
}
If you need thumbnail array throughout the video then use the following API of AVAssetImageGenerator class
func generateCGImagesAsynchronously(forTimes requestedTimes: [NSValue],
completionHandler handler: #escaping AVAssetImageGeneratorCompletionHandler)
For required thumbnail image resolution set the following property
assetImageGenerator.maximumSize
I want to directly open the 'Camera Roll' album using the imagePickerController instead of showing all 3 albums (camera roll, photo library, last import).
Is there any way to do that?
Use
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
It will directly take you to camera roll.
It is very simple to do that ...
For an example of a button ... You click on the button and then try to use :
imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
By using that you will force the Controller to use the camera.
.
[self presentModalViewController:imgPicker animated:YES];
imgPicker is here the name of my controller
To achieve this you have only oneway..
You can create customImagePickerController and grab display all camera roll images in it.
For that you can use collectionview
or else
https://github.com/rahulmane91/CustomAlbumDemo
May this useful to you.
Thanks & Regards
Nirav Zalavadia
make use of Photos Framework
#property(nonatomic , strong) PHFetchResult *assetsFetchResults;
NSMutableArray *array;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", #"Custom Photo Album"];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
_assetsFetchResults = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
Use the above code and put your album name whose data you want to Fetch in the place of "Custom Photo Album"
PHFetchResult *collectionResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
for (int h=0; h<[collectionResult count]; h++) {
PHAsset *asset1 = collectionResult[h];
[_imageManager requestImageForAsset:asset1 targetSize:frame.size contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info)
{
[array2 addObject:result];
}];
}
NSLog(#"array count%lu",(unsigned long)[array2 count]);
and use the array anywhere you want to display all albums images
Tou can use this code to access directly
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum
but you will have to have a better UI
Try this framework which gives both cam and cam roll
https://github.com/hyperoslo/ImagePicker
https://github.com/hyperoslo/Gallery
I am picking an image from photo library in iphone application. How will i retrieve the actual image name.
in .h class
UIImageView * imageView;
UIButton * choosePhotoBtn;
in .m class
-(IBAction) getPhoto:(id) sender
{
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIButton *) sender == choosePhotoBtn)
{
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
else
{
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissModalViewControllerAnimated:YES];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
How will i get the actual name of image ?
I m new in iphone. Please help me.
Thanks in advance.
import AssetsLibrary in your file:
#import <AssetsLibrary/AssetsLibrary.h>
And, in - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
put
// get the ref url
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
// define the block to call when we get the asset based on the url (below)
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"[imageRep filename] : %#", [imageRep filename]);
};
// get the asset library and fetch the asset based on the ref url (pass in block above)
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:refURL resultBlock:resultblock failureBlock:nil];
so you'll get the image name in log.
*don't forget to add existing framework: AssetsLibrary.framework
Steps:
In the project navigator, select your project
Select your target
Select the 'Build Phases' tab
Open 'Link Binaries With Libraries' expander
Click the '+' button
Select your framework
(optional) Drag and drop the added framework to the 'Frameworks' group
Source:
http://www.raywenderlich.com/forums/viewtopic.php?f=2&p=34901
&
How to "add existing frameworks" in Xcode 4?
If you are building for iOS 9+ target, you will see a bunch of deprecation warnings with ALAssetsLibrary, i.e.:
'assetForURL(_:resultBlock:failureBlock:)' was deprecated in iOS 9.0: Use fetchAssetsWithLocalIdentifiers:options: on PHAsset to fetch assets by local identifier (or to lookup PHAssets by a previously known ALAssetPropertyAssetURL use fetchAssetsWithALAssetURLs:options:) from the Photos framework instead
As the warning describes, you should use PHAsset. Using swift 2.x, for example, you will need to add import Photos to your file first. Then, in the didFinishPickingMediaWithInfo UIImagePickerControllerDelegate method use fetchAssetsWithALAssetURLs to get the filename:
if let imageURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
let result = PHAsset.fetchAssetsWithALAssetURLs([imageURL], options: nil)
let filename = result.firstObject?.filename ?? ""
}
This will set filename to be something like, "IMG_0007.JPG".
Simple Swift implementation:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let referenceUrl = info[UIImagePickerControllerReferenceURL] as? NSURL {
ALAssetsLibrary().assetForURL(referenceUrl, resultBlock: { asset in
let fileName = asset.defaultRepresentation().filename()
//do whatever with your file name
}, failureBlock: nil)
}
}
}
Remember about: import AssetsLibrary
In Objective C, use the Photos framework and import Photos/Photos.h
Then, in your imagePickerController function
add the following to get the filename of the image from the photo library
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[refURL] options:nil];
NSString *filename = [[result firstObject] filename];
Though you may be able to retrieve the last path component and use it like a file name, it is not advisable to do so. These filenames are assigned by the system for iTunes to understand while syncing and are not meant for programmers to access as they could be replaced by some other images in future syncs.
A good round about for this is to assign the current Date as filenames, while saving to images picked from the gallery. You may save it in your documents or library directory and use a mapping PList file to map images to their filename.
Alternatively, you can also assign unique numbers as filenames and access the images using these values.
Objective C implementation that works on iOS 10. ALAssetsLibrary seems to be deprecated so you should use PHAsset:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHAsset *phAsset = [[PHAsset fetchAssetsWithALAssetURLs:#[imageURL] options:nil] lastObject];
NSString *imageName = [phAsset valueForKey:#"filename"];
UIImage *photo = [info valueForKey:UIImagePickerControllerOriginalImage];
NSLog(#"Picked image: %# width: %f x height: %f",imageName, photo.size.width, photo.size.height);
[picker dismissViewControllerAnimated:YES completion:nil];
}
As of Swift 3 and iOS8+ the .filename is not accessible any more. It is still available through self.valueForKey("filename"), but not quite legal though.
However, I found this answer in the question "iOS8 Photos Framework: How to get the name(or filename) of a PHAsset?" to be short, simple, and legal.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
let image = info[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
do
{
try data?.write(to: localPath!, options: Data.WritingOptions.atomic)
}
catch
{
// Catch exception here and act accordingly
}
self.dismiss(animated: true, completion: nil);
}
var fileName: String = "Attachment"
if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
let assets = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
let assetResource = PHAssetResource.assetResources(for: assets.firstObject!)
fileName = assetResource.first?.originalFilename ?? "Attachment"
}
print(fileName)