Im trying to get the image name using PHAssets
. But I couldn't find metadata for filename or any method to get the image name. Is there a different way to get the file name?

- 59,234
- 49
- 233
- 358

- 442
- 1
- 5
- 13
8 Answers
I know the question has already been answered, but I figured I would provide another option:
extension PHAsset {
var originalFilename: String? {
var fileName: String?
if #available(iOS 9.0, *) {
let resources = PHAssetResource.assetResources(for: self)
if let resource = resources.first {
fileName = resource.originalFilename
}
}
if fileName == nil {
/// This is an undocumented workaround that works as of iOS 9.1
fileName = self.value(forKey: "filename") as? String
}
return fileName
}
}
-
1Note that `PHAssetResource` is available on iOS 9+ only. – lobianco Mar 09 '16 at 22:05
-
I tried using your code with a sort descriptor using 'originalFilename' as key and it gives the 'Unsupported sort descriptor in fetch options' error. – Angelo May 03 '16 at 14:40
-
For some reason my video file says "TPHM1745" as the name of the file when I use ImageCapture app in OSX to see the Camera Roll files, but your method throws "IMG_6564.MP4" – omarojo Jul 25 '18 at 22:49
If you want to get the image name (for example name of last photo in Photos) like IMG_XXX.JPG, you can try this:
PHAsset *asset = nil;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
// get last photo from Photos
asset = [fetchResult lastObject];
}
if (asset) {
// get photo info from this asset
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
NSLog(@"info = %@", info);
if ([info objectForKey:@"PHImageFileURLKey"]) {
// path looks like this -
// file:///var/mobile/Media/DCIM/###APPLE/IMG_####.JPG
NSURL *path = [info objectForKey:@"PHImageFileURLKey"];
}
}];
}
Hope it helps.
In Swift the code will look like this
PHImageManager.defaultManager().requestImageDataForAsset(asset, options: PHImageRequestOptions(), resultHandler:
{
(imagedata, dataUTI, orientation, info) in
if info!.keys.contains(NSString(string: "PHImageFileURLKey"))
{
let path = info![NSString(string: "PHImageFileURLKey")] as! NSURL
}
})
Swift 4:
let fetchResult = PHAsset.fetchAssets(with: .image, options: nil)
if fetchResult.count > 0 {
if let asset = fetchResult.firstObject {
let date = asset.creationDate ?? Date()
print("Creation date: \(date)")
PHImageManager.default().requestImageData(for: asset, options: PHImageRequestOptions(),
resultHandler: { (imagedata, dataUTI, orientation, info) in
if let info = info {
if info.keys.contains(NSString(string: "PHImageFileURLKey")) {
if let path = info[NSString(string: "PHImageFileURLKey")] as? NSURL {
print(path)
}
}
}
})
}
}

- 2,418
- 23
- 26
-
5This is just dirty workaround. `PHImageFileURLKey` is undocumented key and also this URL does not have unique name in last path component if image is edited (with image filter for example). – user500 Apr 07 '15 at 18:36
-
Will the fluff always be file:///var/mobile/Media/DCIM/###APPLE/IMG_####.JPG ? Is there some way to cipher through that and just get the file name for instance test.png? – Nerdy Lime Apps Oct 04 '15 at 23:42
-
1And is there any way from keeping the system from renaming images? If I transfer an image to my device, I would like it to maintain the same filename they have on my computer from which I am transporting them and then importing them into the app. Does that make since? – Nerdy Lime Apps Oct 04 '15 at 23:57
-
1
-
What about if you want to get the name like "18-09-04 14-57-30 1905"? – IndexOutOfDevelopersException Sep 04 '18 at 12:57
-
1@wanttobeprofessional please see updated answer. You can find a date in asset.creationDate property, then format it like you want with (NS)DateFormatter. – Eridana Sep 04 '18 at 13:44
One more option is:
[asset valueForKey:@"filename"]
The "legality" of this is up to you to decide.

- 56,823
- 9
- 150
- 195
-
3There is no property named 'filename' for PHAsset. How can it work? – Utsav Dusad Jul 05 '16 at 06:50
-
Magic. =] It's a private property, not exposed in public API. It's relatively to use because there are other, public API, properties called `filename`. – Léo Natan Jul 05 '16 at 06:52
-
1@CaseyHancock I think so. Looking at the time the answer was posted, it was _most likely_ tested on iOS 8. Make sure to test in order to be sure. – Léo Natan Mar 27 '17 at 21:51
Easiest solution for iOS 9+ in Swift 4 (based on skims answer):
extension PHAsset {
var originalFilename: String? {
return PHAssetResource.assetResources(for: self).first?.originalFilename
}
}

- 6,622
- 5
- 46
- 60
-
1
-
1This will give the original filename.. but not the new one that CameraRoll gives to the file. – omarojo Jul 25 '18 at 22:40
-
For Swift
asset?.value(forKey: "filename") as? String
For objective C
[asset valueForKey:@"filename"]

- 63
- 5
Simplest answer with Swift when you have reference URL to an asset:
if let asset = PHAsset.fetchAssetsWithALAssetURLs([referenceUrl], options: nil).firstObject as? PHAsset {
PHImageManager.defaultManager().requestImageDataForAsset(asset, options: nil, resultHandler: { _, _, _, info in
if let fileName = (info?["PHImageFileURLKey"] as? NSURL)?.lastPathComponent {
//do something with file name
}
})
}

- 19,824
- 17
- 99
- 186

- 59,234
- 49
- 233
- 358
SWIFT4:
first import Photos
if let asset = PHAsset.fetchAssets(withALAssetURLs: [info[UIImagePickerControllerReferenceURL] as! URL],
options: nil).firstObject {
PHImageManager.default().requestImageData(for: asset, options: nil, resultHandler: { _, _, _, info in
if let fileName = (info?["PHImageFileURLKey"] as? NSURL)?.lastPathComponent {
print("///////" + fileName + "////////")
//do sth with file name
}
})
}

- 1,056
- 11
- 21
What you really looking for is the localIdentifier which is a unique string that persistently identifies the object.
Use this string to find the object by using the:
fetchAssetsWithLocalIdentifiers:options:, fetchAssetCollectionsWithLocalIdentifiers:options:, or fetchCollectionListsWithLocalIdentifiers:options: method.
More information is available here

- 1,868
- 23
- 32