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)
Related
I am making a project very similiar to Instagram's multiple image post feature, and I have 2 errors that are connected to each other in my capturePhotoController because of my ImageUploadManager. The errors are:
Cannot assign to immutable expression of type 'ImageUploadManager.Type'
Type 'ImageUploadManager?' has no member 'uploadImage'
It is happening in this view controller: *The errors are marked with a comment
import UIKit
class takePicViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.allowsEditing = false
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
// Error ImageUploadManager = ImageUploadManager()
// Error ImageUploadManager?.uploadImage(userPickedImage, progressBlock: { (percentage) in
print(percentage)
}, completionBlock: { (fileURL, errorMessage) in
print(fileURL)
print(errorMessage)
})
PhotoArray.sharedInstance.photosArray.append(userPickedImage) //append converted data in array
imageView.image = userPickedImage
}
imagePicker.dismiss(animated: true, completion: nil)
}
#IBAction func cameraButtonPressed(_ sender: UIButton) {
present(imagePicker, animated: true, completion: nil)
}
}
Here is the code for the ImageUploadManager:
import UIKit
import FirebaseStorage
import Firebase
struct Constants {
struct Car {
static let imagesFolder: String = "carImages"
}
}
class ImageUploadManager: NSObject {
func uploadImage(_ image: UIImage, /**/ progressBlock: #escaping (_ percentage: Double) -> Void, /**/ completionBlock: #escaping (_ url: String?, _ errorMessage: String?) -> Void) {
let data = Data()
let storage = Storage.storage()
let storageRef = storage.reference()
let imageName = "\(Date().timeIntervalSince1970).jpg"
let imagesReference = storageRef.child(Constants.Car.imagesFolder).child(imageName)
if let imageData = UIImageJPEGRepresentation(image, 0.8) {
let metadata = storageRef.child("image/jpg")
let uploadTask = metadata.putData(data, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
return
}
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
return
}
}
}
uploadTask.observe(.progress, handler: { (snapshot) in
guard let progress = snapshot.progress else {
return
}
let percentage = (Double(progress.completedUnitCount) / Double(progress.totalUnitCount)) * 100
progressBlock(percentage)
})
} else {
completionBlock(nil, "Image could not be converted to Data.")
}
}
}
Is the commented code:
// Error ImageUploadManager = ImageUploadManager()
your declaration of ImageUploadManager? if so that is totally wrong. It should be declared as below:
if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let imageUploadManager = ImageUploadManager()
imageUploadManager.uploadImage(userPickedImage, prog.....
Reading your ImageUploadManager it looks like it's an stateless object and you can declare your function as a class function.
`class func uploadImage(_ image: UIImage`......`
You can then call it:
if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
ImageUploadManager.uploadImage(userPickedImage, prog.....
I am trying to take a printed item and inserting it into my Firebase Database along with the rest of outlets. Thanks!
#objc(imagePickerController:didFinishPickingMediaWithInfo:) func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
myImageView.image = image
} else {
//error
}
self.dismiss(animated: true, completion: nil)
let storageRef = FIRStorage.storage().reference().child("myImage.png")
if let uploadData = UIImagePNGRepresentation(self.myImageView.image!) {
storageRef.put(uploadData, metadata: nil, completion:
{
(metadata, error) in
if error != nil {
print("error")
return
} else {
print((metadata?.downloadURL()?.absoluteString)!)
//i want to take the line above and insert it into the database
}
})
}
}
#IBAction func addPost(_ sender: Any) {
if self.titleText.text != "" && self.authorText.text != "" && self.mainText.text != "" && self.dateText.text != "" {
ref?.child("Posts").childByAutoId()
.setValue(["Title": titleText.text,
"Article": mainText.text,
"Author": authorText.text,
"Date": dateText.text ])
//insert the download URL above
self.performSegue(withIdentifier: "kost", sender: self)
}
}
I see what your problem is now. You are tackling uploading images to firebase in totally the wrong manner. In the event didFinishPickingMediaWithInfo you should not be doing anything with firebase. You should only be setting your UIImageViews image to store the value of the data given from the image picker.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
self.dismiss(animated: true, completion: nil)
if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage{
myImageView.image = editedImage
}else{
print("Something went wrong")
}
}
Then in your IBAction, you should upload everything to firebase. Here is a simple function that will upload your image to the database it:
func uploadImage(){
if let fileData = UIImageJPEGRepresentation(myImageView.image!, 0.8){
let storageRef = storage.reference().child("images").child("testImage.jpg")
storageRef.put(fileData, metadata: nil, completion: { (metadata, error) in
if error != nil{
print(error?.localizedDescription ?? "error")
return
}
let downloadURL = metadata?.downloadURL()?.absoluteString
// Write the download URL to your Database
self.ref?.child("images").setValue(downloadURL)
})
}else{
print("error")
}
}
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)
}
}
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()
}
}
}
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
}
}