How to get file name in UIImagePickerController with Asset library?

后端 未结 13 1617
天命终不由人
天命终不由人 2020-12-03 14:55

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

相关标签:
13条回答
  • 2020-12-03 15:40
      func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 
    
             if let asset = PHAsset.fetchAssets(withALAssetURLs: [info[UIImagePickerControllerReferenceURL] as! URL],options: nil).firstObject {              
    
                var resources = PHAssetResource.assetResources(for: asset)
    
                let orgFilename: String = ((resources[0] as? PHAssetResource)?.originalFilename)!
    
                print("filename:",orgFilename)
         }
        }
    
    0 讨论(0)
  • 2020-12-03 15:45

    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)
    }
    
    0 讨论(0)
  • 2020-12-03 15:50

    I came cross this question when searching for a way to retrieve filename from UIImagePickerController.

    I tried all the methods mentioned in the answers, but the results were inconsistent.

    As one novice iOS developer my self, I will not try to detail the mechanism between those ways. Instead I will demo my findings.

    Note: all under iOS 13 with Swift 5.

    The first way, which I don't think it's the really file name because it keeps changing. I guess this is the local path name because image picker saves the image to your app's temporary directory.

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
      guard let url = info[.imageURL] as? NSURL else { return }
      let filename = url.lastPathComponent!
      print(filename) // 46484E68-94E8-47B7-B0F4-E52EA7E480A9.jpeg
    }
    

    The second way, which is consitent each time I select it. I think it can be used as file name but not flawless.

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
      let photo = info[.phAsset] as? PHAsset
      var filename = photo?.value(forKey: "filename") as? String ?? ""
      print(filename) // IMG_0228.JPG
    }
    

    The third way gets you the original file name, which is the file name you see in your Mac. Say you AirDrop one photo with name "Apple.jpg" to your phone, only with this way will you get the name "Apple.jpg"

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
      let photo = info[.phAsset] as? PHAsset
      let res = PHAssetResource.assetResources(for: photo!)
      let filename = res[0].originalFilename
      print(filename) // Apple.jpg
    }
    
    0 讨论(0)
  • 2020-12-03 15:50

    For me, it is working perfect,

    if let imgUrl = info[UIImagePickerControllerImageURL] as? URL{
       let imgName = imgUrl.lastPathComponent
       print(imgName)
       let imgExtension = imgUrl.pathExtension
       print(imgExtension)
    }
    
    0 讨论(0)
  • 2020-12-03 15:56

    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"
        }
    
    }
    
    0 讨论(0)
  • 2020-12-03 15:56

    import Photos

    func getFileName(info: [String : Any]) -> String {
    
        if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
            let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
            let asset = result.firstObject
            let fileName = asset?.value(forKey: "filename")
            let fileUrl = URL(string: fileName as! String)
            if let name = fileUrl?.deletingPathExtension().lastPathComponent {
            print(name)
            return name
            }
        }
        return ""
    
    }
    

    call it inside the method "didFinishPickingMediaWithInfo" like so:

    let fileName = getFileName(info: info)
    
    0 讨论(0)
提交回复
热议问题