How Can I Arrange Which Part of Code Work First - ios

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

Related

Error uploading a video to Cloud Storage, but not an image (Swift/Xcode/iOS)

I'm trying to upload a video to Google's Cloud Storage, but hit an error:
BackgroundSession <1EE0DA45-0AA5-45FB-AAB4-1580A53F88A8> error requesting a NSURLSessionUploadTask from background transfer daemon: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 27172 named com.apple.nsurlsessiond was interrupted, but the message was sent over an additional proxy and therefore this proxy has become invalid."
_NSURLErrorFailingURLSessionTaskErrorKey=BackgroundUploadTask <26C123A0-427F-45B9-B7A3-64AEBD19A2AA>.<1>, NSLocalizedDescription=unknown error}
Optional("An unknown error occurred, please check the server response.")
2021-03-01 17:00:28.536123+0000 ForfeitV3.2[72747:1363373] BackgroundSession <1EE0DA45-0AA5-45FB-AAB4-1580A53F88A8> connection to background transfer daemon invalidated
Here's my relevant Swift code:
func timelapsePopup() {
let imagePC = UIImagePickerController()
imagePC.sourceType = .photoLibrary
imagePC.delegate = self
imagePC.sourceType = .savedPhotosAlbum
imagePC.mediaTypes = [String(kUTTypeMovie)]
imagePC.allowsEditing = false
V.timelapse = true
present(imagePC, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if V.timelapse == true { //TIMELAPSE
V.timelapse = false
if let selectedVideo = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
// fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
print("Here's the file URL: ", selectedVideo)
dismiss(animated: true, completion: nil)
brain.submitEvidence(itemIndex: V.indexToBePassed, image: UIImage(), timelapsePath: selectedVideo)
}
myTableView.reloadData()
}
mutating func submitEvidence(itemIndex: Int, image: UIImage, timelapsePath: URL) {
print(timelapsePath.absoluteString)
if timelapsePath.absoluteString != "" {
let item = V.items[itemIndex]
item.timelapseURL = timelapsePath
item.timeSubmitted = getCurrentTime()
item.sentForConfirmation = true
self.saveItem(item: item)
self.addTimelapseToFirestore(item: item)
} else {
let item = V.items[itemIndex]
item.image = image.toString()!
item.timeSubmitted = getCurrentTime()
item.sentForConfirmation = true
self.saveItem(item: item)
self.addToFirestore(item: item)
}
}
func addTimelapseToFirestore(item: Item) {
let storage = Storage.storage()
let data = Data()
let storageRef = storage.reference()
let localFile = item.timelapseURL
let photoRef = storageRef.child("videoOne")
let uploadTask = photoRef.putFile(from: localFile!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
print(error?.localizedDescription)
return
}
print("video uploaded")
}
}
The weird thing is that it works when uploading an image. Ie if I change the kUTypeMovie to kUTypeImage, and a few other things to make images work, it uploads that just fine to Cloud Storage. When i switch it back to video, it fails.
All help greatly appreciated - let me know if there's any other info you need!
Cheers,
Josh
Please use the following code which uses UIImagePicker object class to select a video or image in your device and upload it to Firebase ( I have made some changes in your code):
#IBAction func uploadButton(_ sender: Any) {
// Configuration
let picker = UIImagePickerController()
picker.allowsEditing = true
picker.delegate = self
picker.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
// Present the UIImagePicker Controller
present(picker, animated: true, completion: nil)
}
// The didFinishPickingMediaWithInfo let's you select an image/video and let's you decide what to do with it.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if V.timelapse == true { //TIMELAPSE
V.timelapse = false
if let selectedVideo = info[UIImagePickerControllerMediaURL] as? NSURL {
// fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
print("Here's the file URL: ", selectedVideo)
dismiss(animated: true, completion: nil)
brain.submitEvidence(itemIndex: V.indexToBePassed, image: UIImage(), timelapsePath: selectedVideo)
}
myTableView.reloadData()
}
mutating func submitEvidence(itemIndex: Int, image: UIImage, timelapsePath: URL) {
print(timelapsePath.absoluteString)
if timelapsePath.absoluteString != "" {
let item = V.items[itemIndex]
item.timelapseURL = timelapsePath
item.timeSubmitted = getCurrentTime()
item.sentForConfirmation = true
self.saveItem(item: item)
self.addTimelapseToFirestore(item: item)
} else {
let item = V.items[itemIndex]
item.image = image.toString()!
item.timeSubmitted = getCurrentTime()
item.sentForConfirmation = true
self.saveItem(item: item)
self.addToFirestore(item: item)
}
}
func addTimelapseToFirestore(item: Item) {
let storage = Storage.storage()
let data = Data()
let storageRef = storage.reference()
let localFile = item.timelapseURL
let photoRef = storageRef.child("videoOne.mov")
let uploadTask = photoRef.putFile(from: localFile!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
print(error?.localizedDescription)
return
}
print("video uploaded")
}
}
Please let me know if it works for you.

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.

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

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

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