Swift 3.0 Getting URL of UIImage selected from UIImagePickerController - ios

Note:- This question is only for Swift 3.0
I am able to get the path prio to Swift 3.0
I want to get UIImage's path picked in didFinishPickingMediaWithInfo method
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!)
But this path is not pointing to my image, Even there is no any image in Documents folder.
Can anyone help me on this?

You can't access the path of the picked image directly. You need to save that in your DocumentsDirectory and then take the image back with the path.
Do this
Swift 3.x
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
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!)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
}
Also note that you are using the name as the last path component which is same for every file. So, this will save your image in DocumentDirectory only once as it will find the path next time.
Now when you access the localPath variable and navigate to the path, you will find the image.
NOTE:
If you are using a device here, then you need to download the container of the device, show its package contents and navigate to the Documents Directory where you will find your saved image.

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)
}

Related

Error on image capture with camera mode

I'm working on image picker with camera and gallery and using following code to get image captured from camera but imageurl and image name is nil.I'm testing on mobile with os version of 11.2.2.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
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!)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
}
Use UIImagePickerControllerImageURL instead of UIImagePickerControllerReferenceURL like this:
let imageUrl = info[UIImagePickerControllerImageURL] as? NSURL
You will not get any imageUrl or imageName because you are using the camera mode and that image is still not saved in your gallery and hence no image path is created for that camera clicked pic. So they will be nil. You can only get the UIImage object info[UIImagePickerControllerOriginalImage] in this case.
If you pick the image from photo album, then you will get everyhting. You can get the url by info[UIImagePickerControllerImageURL] and you can grab the name using the last path component.
Change your imagePickerController source to photo imagePickerController.sourceType = .photoLibrary and then you will get the urls.

Check if photo still exists in camera roll after restart ios app

I'm still new in iOS development and I'm creating an app that allows to select some photos and access them quickly.
In CoreData, I store the referenceUrl of the photo instead of the photo itself. I'm able to load photos when starting the app this way.
But, before loading photos, I need to check that they still exist and cannot figure out how to check, using the referenceUrl, if a photo exists or not.
Even using the localPath does not work. It returns false all the time.
If you have any idea how I can proceed, I'll be very grateful.
Thanks.
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 localPathString = String(describing: localPath)
let fileManager = FileManager.default
if fileManager.fileExists(atPath: localPathString){
print ("Photo exists")
} else{
print ("Photo does not exist")
}
}
I found a solution, here it is.
I use imageUrl from my code above like that:
let assets = PHAsset.fetchAssets(withALAssetURLs: [imageUrl as URL], options: nil)
if assets.firstObject != nil {
//Then the image is still there
}
else{
//The image is not present anymore
}
Hope that helps.

How to save image or video from UIPickerViewController to document directory?

Handle selected image or video:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("ok")
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
//what to do to save that image
} else {
//how to get the video and save
}
}
Save it to the document directory:
let path = try! NSFileManager.defaultManager().URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: false)
let newPath = path.URLByAppendingPathComponent("image.jpg") //or video.mpg for example
How to save that image to following newPath?
Use following steps to save Image to documents directory
Step 1: Get a path to document directory
let path = try! NSFileManager.defaultManager().URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: false)
Step 2: Append FileName in path
let newPath = path.stringByAppendingPathComponent("image.jpg")
Step 3: Decide filetype of Image either JPEG or PNG and convert image to data(byte)
//let pngImageData = UIImagePNGRepresentation(image) // if you want to save as PNG
let jpgImageData = UIImageJPEGRepresentation(image, 1.0) // if you want to save as JPEG
Step 4: write file to created path
let result = jpgImageData!.writeToFile(newPath, atomically: true)
Add above code into your didFinishPickingImage function.
Use following func to save video to documents directory
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
// *** store the video URL returned by UIImagePickerController *** //
let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
// *** load video data from URL *** //
let videoData = NSData(contentsOfURL: videoURL)
// *** Get documents directory path *** //
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
// *** Append video file name *** //
let dataPath = documentsDirectory.stringByAppendingPathComponent("/videoFileName.mp4")
// *** Write video file data to path *** //
videoData?.writeToFile(dataPath, atomically: false)
}
Updating the accepted answer to Swift 3 in Xcode 8.3.3
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
let path = try! FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
let newPath = path.appendingPathComponent("image.jpg")
let jpgImageData = UIImageJPEGRepresentation(image, 1.0)
do {
try jpgImageData!.write(to: newPath)
} catch {
print(error)
}
} else {
let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
let videoData = NSData(contentsOf: videoURL as URL)
let path = try! FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
let newPath = path.appendingPathComponent("/videoFileName.mp4")
do {
try videoData?.write(to: newPath)
} catch {
print(error)
}
}
}
Swift 5
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[.editedImage] as? UIImage else {
print("No image found")
return
}
// saving to application directory
let imageName = UUID().uuidString
let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)
if let jpegData = image.jpegData(compressionQuality: 0.8) {
print("Image Save to path \(imagePath)")
try? jpegData.write(to: imagePath)
}
}

Getting URL of UIImage from UIImagePickerController

I'm trying to get the URL of an image imported from Library in Swift to send it to Apple Watch with transferFile(_:metadata) but I'm having two error on NSURL.
This is my code:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!)
{
imagePicked.image = image
let imageUrl = editingInfo[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.path!.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String!
let localPath = documentDirectory.stringByAppendingPathComponent(imageName)
let image = editingInfo[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath, atomically: true)
let photoURL = NSURL(fileURLWithPath: localPath)
self.dismissViewControllerAnimated(true, completion: nil);
}
And I'm getting error with *imageName and *localPath because it says that:
'lastPathComponent' is unavailable: Use lastPathComponent on NSURL instead.
'stringByAppendingPathComponent' is unavailable: Use URLByAppendingPathComponent on NSURL instead.
But I can't get it right in Swift 2.0 and Xcode 7. Where am I going wrong?
Apple has changed something in their NSString and NSURL library in their latest release (iOS 9), but those methods are available from iOS 4. You can check the related Apple Forum Post for more details.
For fixing this error, you need to change the code like:
Swift 2:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!)
{
let imageUrl = editingInfo[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.URLByAppendingPathComponent(imageName!)
let image = editingInfo[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath.absoluteString, atomically: true)
self.dismissViewControllerAnimated(true, completion: nil);
}
Swift 3:
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);
}
Reference:
lastPathComponent
URLByAppendingPathComponent:
As of iOS 11, you can get the image URL from the info dictionary with the key UIImagePickerControllerImageURL.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageURL = info[UIImagePickerControllerImageURL] as? URL
}
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)
}

Getting URL of UIImage selected from UIImagePickerController

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:
/Users/Eugene/Library/Developer/CoreSimulator/Devices/3C5E9A23-8220-4B37-BD14-F1E42EEC2C7C/data/Containers/Data/Application/20EBAAE2-6C6F-4651-A48F-16A222CCB3A2/Documents/asset.JPG
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!
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)
}
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)
}
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)
}
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)
}
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
})
}
}
In swift 4
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imgUrl = info[UIImagePickerControllerReferenceURL] as? URL{
let imgName = imgUrl.lastPathComponent
let documentDirectory = NSTemporaryDirectory()
let localPath = documentDirectory.appending(imgName)
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImageJPEGRepresentation(image, 0.3)! as NSData
data.write(toFile: localPath, atomically: true)
let photoURL = URL.init(fileURLWithPath: localPath)
}
}
swift 4.2
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//obtaining saving path
let fileManager = FileManager.default
let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
let imagePath = documentsPath?.appendingPathComponent("image.jpg")
// extract image from the picker and save it
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
let imageData = pickedImage.jpegData(compressionQuality: 0.75)
try! imageData?.write(to: imagePath!)
}
}
Thanks
let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL

Resources