How to get file name in UIImagePickerController with Asset library?

34,989

Solution 1

I will suggest you to use Photos Framework to get the name of the image, below is the code to get name of selected image

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
        let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
        let asset = result.firstObject
        print(asset?.value(forKey: "filename"))

    }

    dismiss(animated: true, completion: nil)
}

Solution 2

Before iOS 11

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
        let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
        let assetResources = PHAssetResource.assetResources(for: result.firstObject!)

        print(assetResources.first!.originalFilename)
    }

    dismiss(animated: true, completion: nil)
}

After iOS 11

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let asset = info[UIImagePickerControllerPHAsset] as? PHAsset {
        let assetResources = PHAssetResource.assetResources(for: asset)

        print(assetResources.first!.originalFilename)
    }

    dismiss(animated: true, completion: nil)
}

Solution 3

Here is how I did it in swift 4

if let url = info[UIImagePickerController.InfoKey.imageURL] as? URL {
        fileName = url.lastPathComponent
        fileType = url.pathExtension
    }

Solution 4

Update 6th May 2018

Forced unwrapped optionals sometimes return nil, I think it's because user use Camera to capture a new image instead of selecting one from Photos library. I updated the code to return a generated name when I see nil.

Original answer

This works for me without having to rely on filename key (please excuse for force unwrap optionals :) )

extension MyViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else {
            DDLogDebug("No image chosen")
            return
        }

        if let url = info[UIImagePickerControllerReferenceURL] as? URL {
            let assets = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil)
            if let firstAsset = assets.firstObject,
            let firstResource = PHAssetResource.assetResources(for: firstAsset).first {
                fileName = firstResource.originalFilename
            } else {
                fileName = generateNameForImage()
            }
        } else {
            fileName = generateNameForImage()
        }

        DDLogDebug("File name = \(fileName)")

        dismiss(animated: true)
    }

    func generateNameForImage() -> String {
        return "IMG_random_string"
    }

}

Solution 5

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    var selectedFileName = ""
    if #available(iOS 11.0, *) {
        if let imageUrl = info[.imageURL] as? URL {
            selectedFileName = imageUrl.lastPathComponent
        }
    } else {
        if let imageURL = info[.referenceURL] as? URL {
            let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
            if let firstObject = result.firstObject {
                let assetResources = PHAssetResource.assetResources(for: firstObject)
                selectedFileName = assetResources.first?.originalFilename
            }
        }
    }

    picker.dismiss(animated: true, completion: nil)
}
Share:
34,989
TechChain
Author by

TechChain

I have 4+ of experience of overall experience.Currently working on Hyperledger Fabric blockchain framework. I have strong knowledge of Objective c, Swift.I have developed lot of apps from chat app, finance apps,location & map based apps.

Updated on February 22, 2021

Comments

  • TechChain
    TechChain about 3 years

    I want to get the file name from UIImagePickerController. I do not want to use ALAssetLibrary because it is deprecated in iOS 9. I have used the following code but it always returns the image name as "Asset.jpg" for each file.

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {       
        let originalImage = (info[UIImagePickerControllerOriginalImage] as? UIImage)!
        let url = info[UIImagePickerControllerReferenceURL] as! NSURL
        imageData = UIImageJPEGRepresentation(originalImage, 100) as NSData?
        let data = UploadData()
        data.fileName = url.lastPathComponent     
        picker.dismiss(animated: true, completion: nil)
    }