Not getting image path - ios

I'm using UIImagePickerController to pick image i want path of selected image but I can't get it.
what I'm trying in code:
func handleImg() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicer : UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicer = editedImage
} else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicer = originalImage
}
if let selectedImage = selectedImageFromPicer {
img.image = selectedImage
}
if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
let asset = result.firstObject
var imgStr = asset?.value(forKey: "filename")
print(imgStr!)
}
dismiss(animated: true, completion: nil)
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("canceled picker")
dismiss(animated: true, completion: nil)
}
}
By above code I can only get the name of image. I want path of image.

If you print the info object you will see all available keys for accessing the values of this dictionary. The image path key is UIImagePickerControllerImageURL
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let imageUrl = info["UIImagePickerControllerImageURL"] as? URL else {
return
}
print(imageUrl.path) // prints the path
picker.dismiss(animated: true, completion: nil)
}

Following code may help you in get the image path.
Code to show UIImagePickerController.
#IBAction func showPicker(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = UIImagePickerControllerSourceType.savedPhotosAlbum
picker.allowsEditing = false
present(picker, animated: true, completion: nil)
}
Delegate method didFinishPickingMediaWithInfo.
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!)
//Check these values
self.dismiss(animated: true, completion: nil);
}

Related

How to change imageView in header cell after pick a photo from imagePickerController?

I have a custom header cell in a collection view. Below is how I set my image from url in my header
let profileImage: UIImageView = {
let image = UIImageView()
image.contentMode = .scaleAspectFill
image.layer.cornerRadius = 42
image.layer.masksToBounds = true
return image
}()
var userInfo: CauNguyenUserInfoModel?{
didSet{
if let profileImageUrl = userInfo?.profileImageUrl {
if let imageUrl = URL(string: profileImageUrl) {
profileImage.sd_setImage(with: imageUrl, placeholderImage: #imageLiteral(resourceName: "default_avatar"), options: [.continueInBackground, .progressiveDownload], completed: nil)
}
}
}
}
I then use protocol and delegation to pass action from a button in my header class to collection view class and using UIImagePickController to select different image from user device
This is func from my collection View controller not from header class
func changeProfileImageBtnPressed() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
present(imagePickerController, animated: true, completion: nil)
}
and using this function to get image file
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
print(editedImage)
}
dismiss(animated: true, completion: nil)
}
My question is after user select an image from his device and I have the image file, how do I change the image in my header class with that image? I put picker func in my collection view controller.
Here you go.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
var newImage: UIImage?
if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
newImage = editedImage
} else if let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
newImage = originalImage
}
imageView.image = image
picker.dismiss(animated: true)
}

UIImagepicker is uploading to the wrong Firebase storage

I have two image views that I'm are used to have the user upload their photos on. When I go to upload the main profile picture everything runs fine and the image gets stored in the appropriate Firebase storage child, but when I press the next image view to upload my next photo, it gets stored in the wrong Firebase Storage.
I tried fixing this problem by having two separate uiimagepickers, but that didn't seem to solve the issue. So my question is, why is it when I press SecondPhoto, it uploads to Profile_Images and not Second_Images which is what I want?
import UIKit
import Firebase
import FBSDKLoginKit
class ProfileViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var secondPhoto: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.frame.size.width / 2;
self.imageView.layer.cornerRadius = 24
self.imageView.clipsToBounds = true;
self.secondPhoto.layer.cornerRadius = self.secondPhoto.frame.size.height / 2;
secondPhoto.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSecondProfileImageView)))
profilePicture.addGestureRecognizer(UITapGestureRecognizer(target:self, action: #selector(handleSelectProfileImageView)))
let uid = FIRAuth.auth()?.currentUser?.uid
FIRDatabase.database().reference().child("Users").child(uid!).observeSingleEvent(of: .value, with: {(snapshot) in if let dictionary = snapshot.value as? [String: AnyObject]
{
self.imageView.loadImageUsingCachWithUrlString(urlString:dictionary["profileImageUrl"] as! String)
self.secondPhoto.loadImageUsingCachWithUrlString(urlString:dictionary["secondImageUrl"] as! String)
}
}, withCancel: nil)
}
func handleSelectProfileImageView() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion:nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker:UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage{
selectedImageFromPicker = editedImage
}else if let originalImage = info["UIIMagePickerControllerOriginalImage"] as? UIImage{
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker{
updateProfileImageInFirebase(image: selectedImage)
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("canceled picker")
dismiss(animated: true, completion: nil)
}
func updateProfileImageInFirebase(image: UIImage){
let user = FIRAuth.auth()?.currentUser
guard let uid = user?.uid else {
return
}
if user != nil {
let imageName = NSUUID().uuidString
let storageRef = FIRStorage.storage().reference().child("Profile_Images").child("\(imageName).jpg")
if let uploadData = UIImageJPEGRepresentation(image, 0.1) {
storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
if error != nil {
print(error!)
return
}
if let profileImageUrl = metadata?.downloadURL()?.absoluteString {
FIRDatabase.database().reference().child("Users").child(uid).updateChildValues(["profileImageUrl": profileImageUrl])
}
})
}
}
}
func handleSecondProfileImageView() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion:nil)
}
func secondimagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker:UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage{
selectedImageFromPicker = editedImage
}else if let originalImage = info["UIIMagePickerControllerOriginalImage"] as? UIImage{
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker{
updatesecondAvatarImageInFirebase(image: selectedImage)
}
dismiss(animated: true, completion: nil)
}
func secondimagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("canceled picker")
dismiss(animated: true, completion: nil)
}
func updatesecondAvatarImageInFirebase(image: UIImage){
let user = FIRAuth.auth()?.currentUser
guard let uid = user?.uid else {
return
}
if user != nil {
let imageName = NSUUID().uuidString
let storageRef = FIRStorage.storage().reference().child("Second_Images").child("\(imageName).jpg")
if let uploadData = UIImageJPEGRepresentation(image, 0.1) {
storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
if error != nil {
print(error!)
return
}
if let secondImageUrl = metadata?.downloadURL()?.absoluteString {
FIRDatabase.database().reference().child("Users").child(uid).updateChildValues(["secondImageUrl": secondImageUrl])
}
})
}
}
}
}
I was able to solve it by adding adding tags to the buttons and using a switch control

Get return value of func imagePickerController(picker: UIImagePickerController, didFinishPackingWithMediaInfo: [String : AnyObject])

I am trying to access NSURL return value of imagePickerController, but I have no idea as what to enter for the parameters. Is it even possible to get the NSURL from this method, if not, how else should I go about obtaining a NSURL from imagePickerControlle?, As I have been searching for days.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) -> NSURL {
let theURL: NSURL = (info[UIImagePickerControllerReferenceURL] as! NSURL)
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profilePicture.image = selectedImage
print("searchthis\(theURL)")
dismiss(animated: true, completion: nil)
return theURL
}
I want to access "theURL" here:
#IBAction func signUpPressed(_ sender: AnyObject) {
let authInfo = AuthInfo()
authInfo.email = emailField.text!
authInfo.firstName = firstField.text!
authInfo.lastName = lastField.text!
authInfo.username = usernameField.text!
authInfo.password = passwordField.text!
authInfo.profilePicture = profilePicture.image
let url = imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo: ).theURL
let container = CKContainer.default()
let privateData = container.privateCloudDatabase
let record = CKRecord(recordType: "Authentication")
record.setValue(authInfo.email, forKey: "email")
record.setValue(authInfo.username, forKey: "username")
record.setValue(authInfo.firstName, forKey: "firstName")
record.setValue(authInfo.lastName, forKey: "lastName")
record.setValue(authInfo.password, forKey: "password")
record.setValue(authInfo.profilePicture, forKey: "profilePicture")
record.setValue(CKAsset(fileURL: ))
privateData.save(record, completionHandler: { record, error in
if error != nil {
print(error)
}
})
}
Thank you!
You have to get the profile image separately and have to save URL and image in global variables.
Like:
//first register your view controller for image picker delegates
#IBAction func profilePickBtnPressed(_ sender: AnyObject) {
let _mediaPicker = UIImagePickerController()
_mediaPicker.delegate = self
_mediaPicker.mediaTypes = ["public.image" as String]
_mediaPicker.allowsEditing = false
_mediaPicker.sourceType = .Camera
self.presentViewController(_mediaPicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//BTW, this is delegate method of picker controller
globalURL = (info[UIImagePickerControllerReferenceURL] as! NSURL)
globalImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profilePicture.image = selectedImage
print("searchthis\(theURL)")
dismiss(animated: true, completion: nil)
}
Then use these globally saved values in this function:
#IBAction func signUpPressed(_ sender: AnyObject) {
let authInfo = AuthInfo()
...
authInfo.profilePicture = globalImage
let url = globalURL
let container = CKContainer.default()
...
}

Uploading Images from UIImage Picker onto new Firebase (Swift)

I have a UIImagePicker set up within my app that works fine. I would like to upload a profile picture to Firebase when my UIImage picker has been chosen. Here is my function for when a picture has been selected.
//image picker did finish code
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
profilePic.contentMode = .ScaleAspectFill
profilePic.image = chosenImage
profilePic.hidden = false
buttonStack.hidden = true
changeButtonView.hidden = false
self.statusLabel.text = "Here is Your Profile Picture"
dismissViewControllerAnimated(true, completion: nil)
}
The new documentation states that we need to declare a NSURl in order to upload a file. Here is my attempt to find the NSURL of the given file, but it doesn't work. Here is the documentation and a link to it:https://firebase.google.com/docs/storage/ios/upload-files#upload_from_data_in_memory
// File located on disk
let localFile: NSURL = ...
// Create a reference to the file you want to upload
let riversRef = storageRef.child("images/rivers.jpg")
// Upload the file to the path "images/rivers.jpg"
let uploadTask = riversRef.putFile(localFile, metadata: nil) { metadata, error in
if (error != nil) {
// Uh-oh, an error occurred!
} else {
// Metadata contains file metadata such as size, content-type, and download URL.
let downloadURL = metadata!.downloadURL
}
}
Here is my attempt for retrieving the NSURL of the UIImagePicker:
//image picker did finish code
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
//getting the object's url
let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String;
let photoUrl = NSURL(fileURLWithPath: documentDir)
let localPath = photoUrl.URLByAppendingPathComponent(imageName!)
self.localFile = localPath
profilePic.contentMode = .ScaleAspectFill
profilePic.image = chosenImage
profilePic.hidden = false
buttonStack.hidden = true
changeButtonView.hidden = false
self.statusLabel.text = "Here is Your Profile Picture"
dismissViewControllerAnimated(true, completion: nil)
}
I believe that I am also running into difficulties if the image was taken from the camera instead of the gallery since it is not saved on the device yet. How do I find this image/snapshots's NSURL?
Here is my method to upload and download the user profile photo from firebase storage:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
userPhoto.image = image
dismissViewControllerAnimated(true, completion: nil)
var data = NSData()
data = UIImageJPEGRepresentation(userPhoto.image!, 0.8)!
// set upload path
let filePath = "\(FIRAuth.auth()!.currentUser!.uid)/\("userPhoto")"
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpg"
self.storageRef.child(filePath).putData(data, metadata: metaData){(metaData,error) in
if let error = error {
print(error.localizedDescription)
return
}else{
//store downloadURL
let downloadURL = metaData!.downloadURL()!.absoluteString
//store downloadURL at database
self.databaseRef.child("users").child(FIRAuth.auth()!.currentUser!.uid).updateChildValues(["userPhoto": downloadURL])
}
}
}
I also store the Image URL into firebase database and check if the user has a profile photo or you might get a crash:
//get photo back
databaseRef.child("users").child(userID!).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
// check if user has photo
if snapshot.hasChild("userPhoto"){
// set image locatin
let filePath = "\(userID!)/\("userPhoto")"
// Assuming a < 10MB file, though you can change that
self.storageRef.child(filePath).dataWithMaxSize(10*1024*1024, completion: { (data, error) in
let userPhoto = UIImage(data: data!)
self.userPhoto.image = userPhoto
})
}
})
Simple 2020 example
Don't forget to add pod 'Firebase/Storage' to your podfile, and pod install
Add two delegates to your class
class YourScreen: UIViewController,
UIImagePickerControllerDelegate, UINavigationControllerDelegate {
Storyboard, button, link to ...
#IBAction func tapCameraButton() {
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
and then
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let im: UIImage = info[.editedImage] as? UIImage else { return }
guard let d: Data = im.jpegData(compressionQuality: 0.5) else { return }
let md = StorageMetadata()
md.contentType = "image/png"
let ref = Storage.storage().reference().child("someFolder/12345678.jpg")
ref.putData(d, metadata: md) { (metadata, error) in
if error == nil {
ref.downloadURL(completion: { (url, error) in
print("Done, url is \(String(describing: url))")
})
}else{
print("error \(String(describing: error))")
}
}
dismiss(animated: true)
}
But where do you put the image?
At the code,
... .child("someFolder/12345678.jpg")
Almost inevitably,
• as the folder name use the user's id, the chat id, the feed id or a similar concept
• for the name, the only possibility is a uuid
Hence almost always
let f = chatId + "/" + UUID().uuidString + ".jpg"
let ref = Storage.storage().reference().child(f)
Working in Swift 4.2
Here i am doing click on image i have added tapGesture then it open gallery then selected image that upload in Firebase and also i add textField Value Too i hope it helps you Thank You
import UIKit
import Firebase
class ViewController: UIViewController {
#IBOutlet var myImageView: UIImageView!
#IBOutlet var txtText: UITextField!
var ref = DatabaseReference.init()
var imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
self.ref = Database.database().reference()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.openGalleryClick(tapGesture:)))
myImageView.isUserInteractionEnabled = true
myImageView.addGestureRecognizer(tapGestureRecognizer)
myImageView.backgroundColor = UIColor.red
}
#objc func openGalleryClick(tapGesture: UITapGestureRecognizer){
self.setupImagePicker()
}
#IBAction func btnSaveClick(_ sender: UIButton) {
self.saveFIRData()
}
func saveFIRData(){
self.uploadMedia(image: myImageView.image!){ url in
self.saveImage(userName: self.txtText.text!, profileImageURL: url!){ success in
if (success != nil){
self.dismiss(animated: true, completion: nil)
}
}
}
}
func uploadMedia(image :UIImage, completion: #escaping ((_ url: URL?) -> ())) {
let storageRef = Storage.storage().reference().child("myimage.png")
let imgData = self.myImageView.image?.pngData()
let metaData = StorageMetadata()
metaData.contentType = "image/png"
storageRef.putData(imgData!, metadata: metaData) { (metadata, error) in
if error == nil{
storageRef.downloadURL(completion: { (url, error) in
completion(url)
})
}else{
print("error in save image")
completion(nil)
}
}
}
func saveImage(userName:String, profileImageURL: URL , completion: #escaping ((_ url: URL?) -> ())){
let dict = ["name": "Yogesh", "text": txtText.text!, "profileImageURL": profileImageURL.absoluteString] as [String : Any]
self.ref.child("chat").childByAutoId().setValue(dict)
}
}
extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate{
func setupImagePicker(){
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
imagePicker.sourceType = .savedPhotosAlbum
imagePicker.delegate = self
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
myImageView.image = image
picker.dismiss(animated: true, completion: nil)
}
}

Uploading UIImage to Parse

I have been having a lot of trouble trying to get my photo picker to pick an image, cast it as a Pffile, then upload it to Parse.
I have currently taped together what I have so I could see it being something simple that I can't see.
The error I get is:
reason: 'PFObject values may not have class: UIImage'
Any Ideas?
#IBAction func selectUser(sender: AnyObject) {
let photoPicker = UIImagePickerController()
photoPicker.delegate = self
photoPicker.sourceType = .PhotoLibrary
self.presentViewController(photoPicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let imageData = UIImageJPEGRepresentation(image, 0.05)
let imageFile = PFFile(name:"image.jpg", data:imageData!)
picSlot.file = imageFile
let currentUser = PFUser.currentUser()
if currentUser != nil {
PFUser.currentUser()?.setObject(image, forKey: "userPic")
}
self.dismissViewControllerAnimated(false, completion: nil)
}
You should use the following:
if currentUser != nil {
PFUser.currentUser()?.setObject(imageFile, forKey: "userPic")
}
You can't explicitly set the UIImage as a member of the PFObject, but you can set a PFFile as a PFObject's attribute.

Resources