Getting URL of UIImage selected from UIImagePickerController

i0S Swift Issue

Question or problem with Swift language programming:

I’m trying to provide a user selection of an image from Photo Library. Thus I’m using UIImagePickerController for selecting. But here comes an issue with getting its initial URL in the file system (I need this for CKAsset).

My code.

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
    let path = imageURL.path!
    let imageName = path.lastPathComponent
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentDirectory = paths.first as String!
    let localPath = documentDirectory + "/" + imageName

    let imageData = NSData(contentsOfFile: localPath)!
    let image = UIImage(data: imageData)!

    picker.dismissViewControllerAnimated(true, completion: nil)

}

imageURL is kinda cryptic. It describes Asset URL, but not one in File System. And it looks like: assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG.

According to this logic the path is /asset.JPG where asset.JPG is a name of the image.

Then I’m accessing my Documents folder and trying to find there a file with path:

Cryptic as well but seems to be a real path for a not existing image… No image with that path can be found. And this makes me sick.

Do I have to save an image from the beginning? Or is there any other way to go?

I’ve looked through several tutorials using AssetsLibrary API but I didn’t find anything useful to solve my problem. Thank you in advance!

How to solve the problem:

Solution 1:

Okay, I’ve solved the issue.

All you have to do is simply grab the image (info[UIImagePickerControllerOriginalImage] as UIImage) and save to the given directory. If you need to save only 1 picture it works great. The code id below.

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
    let imageName = imageURL.path!.lastPathComponent
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
    let localPath = documentDirectory.stringByAppendingPathComponent(imageName)

    let image = info[UIImagePickerControllerOriginalImage] as UIImage
    let data = UIImagePNGRepresentation(image)
    data.writeToFile(localPath, atomically: true)

    let imageData = NSData(contentsOfFile: localPath)!
    let photoURL = NSURL(fileURLWithPath: localPath)
    let imageWithData = UIImage(data: imageData)!

    picker.dismissViewControllerAnimated(true, completion: nil)

}

Solution 2:

In SWIFT 4 u Can Try This, It’s working properly.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {


    if let imgUrl = info[UIImagePickerControllerImageURL] as? URL{
        let imgName = imgUrl.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let localPath = documentDirectory?.appending(imgName)

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        let data = UIImagePNGRepresentation(image)! as NSData
        data.write(toFile: localPath!, atomically: true)
        //let imageData = NSData(contentsOfFile: localPath!)!
        let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
        print(photoURL)

    }

    APPDEL.window?.rootViewController?.dismiss(animated: true, completion: nil)
}

Solution 3:

  func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
//this block of code grabs the path of the file   
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imagePath =  imageURL.path!
let localPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(imagePath)

 //this block of code adds data to the above path
 let path = localPath.relativePath!
 let imageName = info[UIImagePickerControllerOriginalImage] as UIImage
 let data = UIImagePNGRepresentation(imageName)
 data?.writeToFile(imagePath, atomically: true)

//this block grabs the NSURL so you can use it in CKASSET
 let photoURL = NSURL(fileURLWithPath: path)
 }

Solution 4:

check this solution.

 import AssetsLibrary  

     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
          self.imagePicker = picker
          if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            let controller = CropViewController(image: selectedImage )
            controller.delegate = self
            picker.presentViewController(controller, animated: true, completion: nil)
          }

       else if let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL{
          let assetLibrary = ALAssetsLibrary()
          assetLibrary.assetForURL(imageUrl , resultBlock: { (asset: ALAsset!) -> Void in
            if let actualAsset = asset as ALAsset? {
              let assetRep: ALAssetRepresentation = actualAsset.defaultRepresentation()
              let iref = assetRep.fullResolutionImage().takeUnretainedValue()
              let image = UIImage(CGImage: iref)
              let controller = CropViewController(image: image)
              controller.delegate = self
              picker.presentViewController(controller, animated: true, completion: nil)
            }
            }, failureBlock: { (error) -> Void in
          })
        }
      }

Solution 5:

For Swift 5+ ;according to @Jaydip answer

if let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL{
        let imgName = imgUrl.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let localPath = documentDirectory?.appending(imgName)

        let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        let data = image.pngData()! as NSData
        data.write(toFile: localPath!, atomically: true)
        //let imageData = NSData(contentsOfFile: localPath!)!
        let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
        print(photoURL)

    }

Hope this helps!