Swift - Display two separate images in 2 UIImageViews in 1 ViewController - ios

I would like to display two images on one viewcontroller selecting them from the camera roll,
I have managed to get to the camera roll to be able to select them but when I select one image it places them in both UIImageViews.
I want to be able to display two different images in the UIImageView.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//handle media here i.e. do stuff with photo
print("imagePickerController called")
if let chosenImage = info[UIImagePickerControllerEditedImage] {
profileImage.image = chosenImage as? UIImage
let user: PFUser = PFUser.currentUser()!
let profileImageData = UIImageJPEGRepresentation(profileImage.image!, 1)
if (profileImageData != nil)
{
let profileFileObject = PFFile(data: profileImageData!)
user.setObject(profileFileObject!, forKey: "profilePicture")
}
}
Up to here I can select one image and save it to Parse successfully, but when I try and add the other code for the other UIImageView, like this:
if let chosenCoverImage = info[UIImagePickerControllerEditedImage] {
coverImage.image = chosenCoverImage as? UIImage
let coverUser: PFUser = PFUser.currentUser()!
let coverImageData = UIImageJPEGRepresentation(coverImage.image!, 1)
if (coverImageData != nil)
{
let coverFileObject = PFFile(data: coverImageData!)
coverUser.setObject(coverFileObject!, forKey: "coverPicture")
}}
}
That second part of code doesn't seem to work though, basically it shows the same image in both UIImageViews, what I think I need is a second
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
}
But that oviously isn't possible in the same swift file.
Any idea's on how I could achieve this?
Thank you in advance!
Here's my full imagePickerConytoller code:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//handle media here i.e. do stuff with photo
print("imagePickerController called")
let chosenImage = info[UIImagePickerControllerEditedImage] as? UIImage
profileImage.image = chosenImage
let user: PFUser = PFUser.currentUser()!
let profileImageData = UIImageJPEGRepresentation(profileImage.image!, 1)
if (profileImageData != nil)
{
let profileFileObject = PFFile(data: profileImageData!)
user.setObject(profileFileObject!, forKey: "profilePicture")
}
let chosenCoverImage = info[UIImagePickerControllerEditedImage] as? UIImage
coverImage.image = chosenCoverImage
let coverUser: PFUser = PFUser.currentUser()!
let coverImageData = UIImageJPEGRepresentation(coverImage.image!, 1)
if (coverImageData != nil)
{
let coverFileObject = PFFile(data: coverImageData!)
coverUser.setObject(coverFileObject!, forKey: "coverPicture")
}
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
activityIndicator.center = self.profileImage.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.White
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
activityIndicator.color = UIColor.grayColor()
user.saveInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
self.activityIndicator.stopAnimating()
}
dismissViewControllerAnimated(true, completion: nil)
}
And here is how I get them from Parse in my ViewDidLoad :
if (PFUser.currentUser()?.objectForKey("profilePicture") != nil)
{
let userImageFile:PFFile = PFUser.currentUser()?.objectForKey("profilePicture") as! PFFile
userImageFile.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
self.profileImage.image = UIImage(data: imageData!)
})
}
if (PFUser.currentUser()?.objectForKey("coverPicture") != nil)
{
let userCoverFile:PFFile = PFUser.currentUser()?.objectForKey("coverPicture") as! PFFile
userCoverFile.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
self.coverImage.image = UIImage(data: imageData!)
})
}

this isn't going to be complete, but will have the key parts you will need
class ResponsePhotoController: UIViewController, UIImagePickerControllerDelegate
{
var imageType : Int = 0 // use this to track the image type
// 0 for profile
// 1 for cover
in your code to go get the profile image
imageType = 0
and then when you go get the cover image
imageType = 1
and then in the imagePickerController
if imageType == 0
{
// set up the profile picture
}
else
{
// set up the cover image
}

yo can use use a string "CameraFor" here on camera button click.
set string on profile camera button click "ImageForProfile"
set string on Cover camera button click "ImageForCoverPhoto".
class ResponsePhotoController: UIViewController, UIImagePickerControllerDelegate
{
imageType : Int = 0 // use this to find image type public class variable
if CameraFor == "ImageForProfile" {
//set image here for profile
}
else {
//set image here for ImageForCoverPhoto
}
}

Related

Firebase change photoURL

When a user taps their profile photo they have an option to select a new photo. I want to store the photo into my Storage and Database and update the view as soon as the imagePickerController is dismissed the new image shows on the screen, however nothing changes in the database and after logging in and out the old profile image is still there.
var user: User!
var dataBaseRef: DatabaseReference!{
return Database.database().reference()
}
var storageRef: StorageReference!{
return Storage.storage().reference()
}
func updatePhoto() {
let user = Auth.auth().currentUser
let newPhoto = profileImage.image
let imgData = UIImageJPEGRepresentation(newPhoto!, 0.7)!
let imagePath = "profileImage\(user.uid)/userPic.jpg"
let imageRef = storageRef.child(imagePath)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
imageRef.putData(imgData, metadata: metadata) { (metadata, error) in
if error == nil {
let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
if let photoURL = metadata!.downloadURL(){
changeRequest?.photoURL = photoURL
}
changeRequest?.commitChanges(completion: { (error) in
if error == nil{
let user = Auth.auth().currentUser
let userInfo = ["firstLastName": self.nameOld, "email": self.emailString, "password": self.passwordOld, "location": self.locationOld, "interests": self.interestsOld, "biography": self.bioOld, "uid": self.uid, "photoURL": String(describing: user?.photoURL!)]
let userRef = self.dataBaseRef.child("users").child((user?.uid)!)
userRef.setValue(userInfo)
let credential = EmailAuthProvider.credential(withEmail: self.emailString, password: self.passwordOld)
user?.reauthenticate(with: credential) { error in
if let error = error {
print(error)
// An error happened.
} else {
print("AUTHENTICATED")
// User re-authenticated.
}
}
print("user info set")
}
})
}}}
func loadUserInfo(){
let userRef = dataBaseRef.child("users/\(Auth.auth().currentUser!.uid)")
userRef.observe(.value, with: { (snapshot) in
let user = Users(snapshot: snapshot)
if let username = user.firstLastName{
self.name.text = username
self.nameOld = username
}
if let userLocation = user.location{
self.location.text = userLocation
self.locationOld = userLocation
}
if let bio = user.biography{
self.biog.text = bio
self.bioOld = bio
}
if let interests = user.interests{
self.interests.text = interests
self.interestsOld = interests
}
if let imageOld = user.photoURL{
// let imageURL = user.photoURL!
self.storageR.reference(forURL: imageOld).getData(maxSize: 10 * 1024 * 1024, completion: { (imgData, error) in
if error == nil {
DispatchQueue.main.async {
if let data = imgData {
self.profileImage.image = UIImage(data: data)
}
}
}else {
print(error!.localizedDescription)
}
}
)}
}) { (error) in
print(error.localizedDescription)
}
}
override func viewDidLoad() {
super.viewDidLoad()
setGestureRecognizersToDismissKeyboard()
loadUserInfo()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
self.profileImage.image = image
updatePhoto()
}
else if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
self.profileImage.image = image
updatePhoto()
}
self.dismiss(animated: true, completion: nil)
}
From apple documentation, UIImagePickerControllerEditedImage: Specifies an image edited by the user and UIImagePickerControllerOriginalImage: Specifies the original, uncropped image selected by the user.
If the user does not edit the selected image, you should also call updatePhoto() function in order to upload the selected photo:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
self.profileImage.image = image
updatePhoto()
}
else if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
self.profileImage.image = image
updatePhoto()
}
self.dismiss(animated: true, completion: nil)
}

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

How Can I Arrange Which Part of Code Work First

Im trying to update an image stores in parse.com . I have an imageview on my view and there is a default image on that imageview. I can choose photo from library and i can change my imageviews image with photo which i choose from library. But still my code saves default image to parse not the image which i choose from library.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.dismissViewControllerAnimated(true, completion: nil)
profileImage.image = image
}
var objectIds = [String]()
#IBAction func changePp(sender: AnyObject) {
var image = UIImagePickerController()
image.delegate = self
image.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
image.allowsEditing = false
self.presentViewController(image ,animated: true,completion: nil)
var queryU = PFQuery(className:"ProfilePhoto")
queryU.getObjectInBackgroundWithId(self.objectIds[0]) {
(Pp: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let Pp = Pp {
let imageData = UIImagePNGRepresentation(self.profileImage.image!)
let imageFile = PFFile(name: "pImage.png",data: imageData!)
Pp["profilePhoto"] = imageFile
Pp.saveInBackground()
}
}
}
How can i provide saving to parse process after choose photo from library and set to my imageview ?
It is happening due to you are saving image on parse before to choose image from gallery. So please do it after picking the image from library.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.dismissViewControllerAnimated(true, completion: nil)
profileImage.image = image
var queryU = PFQuery(className:"ProfilePhoto")
queryU.getObjectInBackgroundWithId(self.objectIds[0]) {
(Pp: PFObject?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let Pp = Pp {
let imageData = UIImagePNGRepresentation(self.profileImage.image!)
let imageFile = PFFile(name: "pImage.png",data: imageData!)
wait(w_status: 1000)
Pp["profilePhoto"] = imageFile
Pp.saveInBackground()
}
}
}

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.

Upload image to parse

I am new to iOS, I want to upload image to parse. Here is the code
func imagePickerController(picker : UIImagePickerController, didFinishPickingMediaWithInfo info : [NSObject : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let scaledImage = self.scale(pickedImage, and : CGSizeMake(100, 100))
let imagedata = UIImagePNGRepresentation(scaledImage)
let imageFile = PFFile(data : imagedata)
PFUser.currentUser()?.setObject(imageFile, forKey : "profileImage")
PFUser.currentUser()!.saveInBackgroundWithBlock {
(success : Bool, error : NSError?) -> Void in
if (success) {
println("success")//Neither success nor fail is printing
} else {
println("fail")
}
}
// print("")
dismissViewControllerAnimated(true, completion : nil)
let viewcontroller = self.storyboard?.instantiateViewControllerWithIdentifier("yoyo") as? UIViewController
self.presentViewController(viewcontroller!, animated : true, completion : nil)
}
}
The problem is databrowser is not populated with image. Thanks.
You may want to use the saveInBackgroundWithBlock like this
var parseImageFile = PFFile(name: "uploaded_image.png", data: imageData)
posts["imageFile"] = parseImageFile
posts.saveInBackgroundWithBlock({
(success: Bool, error: NSError?) -> Void in
if error == nil {
//back to home
println("Success")
self.performSegueWithIdentifier("something", sender: self)

Resources