I have this code, but I have a problem, because it writes me Use of unresolved identifier 'metadata', Thanks in advance! I am a beginner in Xcode, so please explain well!
I got this out of in a youtube tutorial, from zero2launch!
import UIKit
import FirebaseDatabase
import FirebaseAuth
import FirebaseStorage
class SignUpViewController: UIViewController {
#IBOutlet weak var ProfileImage: UIImageView!
#IBOutlet weak var UsernameField: UITextField!
#IBOutlet weak var PasswordField: UITextField!
#IBOutlet weak var Mailfield: UITextField!
var selectedImage: UIImage?
#IBAction func dismiss_onClick(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
ProfileImage.layer.cornerRadius = 40
ProfileImage.clipsToBounds = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SignUpViewController.handleSelectProfileImageView))
ProfileImage.addGestureRecognizer(tapGesture)
ProfileImage.isUserInteractionEnabled = true
}
#objc func handleSelectProfileImageView() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
#IBAction func SignUpButton(_ sender: Any) {
Auth.auth().createUser(withEmail: Mailfield.text!, password: PasswordField.text! , completion:{(user: User?, error:Error?) in
if error != nil {
print(error!.localizedDescription)
return
}
let uid = user?.uid
let storageRef = Storage.storage().reference(forURL: "gs://gibble-2bed4.appspot.com").child("profile_image").child(uid!)
if let profileImg = self.selectedImage, let imageData = UIImageJPEGRepresentation(profileImg, 0.1){
storageRef.putData(imageData, metadata: nil, completion: { (matadata, error) in
if error != nil{
return
}
let profileImageUrl = metadata?.downloadURL()?.absoluteString
let ref = Database.database().reference()
let usersReference = ref.child("users")
let newUserReference = usersReference.child(uid!)
newUserReference.setValue(["username" : self.UsernameField.text!, "email": self.Mailfield.text!, "profileImageUrl": profileImageUrl])
})
}
})
}
}
extension SignUpViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("did Finish picking Media")
if let image = info["UIImagePickerControllerOriginalImage"] as? UIImage{
selectedImage = image
ProfileImage.image = image
dismiss(animated: true, completion: nil)
}
print(info)
}
}
You initialised matadata instead of metadata (which you want to use) in the closure in your following code (first line: "(matadata, error)"):
storageRef.putData(imageData, metadata: nil, completion: { (matadata, error) in
if error != nil{
return
}
let profileImageUrl = metadata?.downloadURL()?.absoluteString
The metadata in the last line should be matadata or you have to change it in the first line.
Related
I'm simply trying to upload an image but I'm getting this error "[boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
Optional("User does not have permission to access 'here was the link to the folder.' ")"
My goal is to upload a photo and access it later from another page, but now I'm getting this error.
edit: Later I realized that I am getting some of the same error while signing up "[boringssl] boringssl_metrics_log_metric_block_invoke(153)".
The entered user can register and appears in the Firebase interface, but the above error is displayed on the console.
import UIKit
import Firebase
class UploadViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var commentText: UITextField!
#IBOutlet weak var uploadVar: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
imageView.isUserInteractionEnabled = true
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(chooseImage))
imageView.addGestureRecognizer(gestureRecognizer)
}
#IBAction func UploadClicked(_ sender: Any) {
let storage = Storage.storage()
let storageReferance = storage.reference()
let mediaFolder = storageReferance.child("media")
if let data = imageView.image?.jpegData(compressionQuality: 0.5) {
let imageReferance = mediaFolder.child("image.jpg")
imageReferance.putData(data, metadata: nil) { metaData, error in
if error != nil {
print(error?.localizedDescription)
} else {
imageReferance.downloadURL { url, error in
if error == nil {
let imageURL = url?.absoluteString
print(imageURL)
}
}
}
}
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
imageView.image = info[.originalImage] as? UIImage
self.dismiss(animated: true, completion: nil)
}
#objc func chooseImage() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .photoLibrary
present(pickerController, animated: true, completion: nil)
}
}
I am following a tutorial and cannot seem to register my user as the user variable in the Firebase .createUser method appears to be nil. Therefore, when I unwrap it, I get an error.
I have read through a lot of the documentation as well as checked many other questions similar to mine but nothing seems to work
import UIKit
import Firebase
import SwiftKeychainWrapper
class ViewController: UIViewController {
#IBOutlet weak var userImgView: UIImageView!
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
var imagePicker: UIImagePickerController!
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
if let _ = KeychainWrapper.standard.string(forKey: "uid") {
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupUser(userUid: String) {
if let imageData = self.userImgView.image!.jpegData(compressionQuality: 0.2) {
let imgUid = NSUUID().uuidString
let metaData = StorageMetadata()
Storage.storage().reference().child(imgUid).putData(imageData, metadata: metaData) { (metadata, error) in
let downloadURL = metadata
let userData = [
"username": self.usernameField.text!,
"userImg": downloadURL!
] as [String : Any]
Database.database().reference().child("users").child(userUid).setValue(userData)
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
#IBAction func signInPressed(_ sender: Any) {
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password) { user, error in
if error != nil && !(self.usernameField.text?.isEmpty)! {
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
self.performSegue(withIdentifier: "toFeed", sender: nil)
let userID = (user?.user.uid)!
self.setupUser(userUid: userID)
KeychainWrapper.standard.set(userID, forKey: "uid")
}
} else {
if let userID = (user?.user.uid) {
KeychainWrapper.standard.set((userID), forKey: "uid")
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
}
}
#IBAction func getPhoto (_ sender: AnyObject) {
present(imagePicker, animated: true, completion: nil)
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
userImgView.image = image
} else {
print("image wasnt selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
}
The error I am getting is one the "let userID = (user?.user.uid)!". It is
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
The completion block for createUser(withEmail:,password:) gets called with either a AuthResult.user or an error. That why, as Joshua commented, you should check if error is nil before accessing any of the user properties.
From the auth quickstart for Swift:
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
strongSelf.hideSpinner {
guard let user = authResult?.user, error == nil else {
strongSelf.showMessagePrompt(error!.localizedDescription)
return
}
print("\(user.email!) created")
strongSelf.navigationController?.popViewController(animated: true)
}
}
This question already has answers here:
Xcode 8 says "Do you want to add a stub?" How do I answer?
(3 answers)
Closed 4 years ago.
I added the ImageView Protocol. What can be done to remove the error
Do you want to add protocol stubs?
CardsViewController
import UIKit
protocol ImageViewProtocol{
func sendImageToViewController(theImage: UIImage)
}
class CardsViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, ImageViewProtocol {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var locationTextField: UITextField!
#IBOutlet weak var imageView: UIImageView!
#IBAction func goToViewController2Action(_ sender: Any)
{
let viewcontroller2 = storyboard?.instantiateViewController(withIdentifier: "viewController2") as! ViewController2
viewcontroller2.delegate = self
self.navigationController?.pushViewController(viewcontroller2, animated: true)
}
func chooseImagePickerAction(source: UIImagePickerController.SourceType) {
if UIImagePickerController.isSourceTypeAvailable(source) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = source
self.present(imagePicker, animated: true, completion: nil)
}
}
#IBAction func saveButtonPressed(_ sender: UIBarButtonItem) {
if nameTextField.text == "" || locationTextField.text == "" || textField.text == "" {
print("Not all fields are filled")
} else {
if let context = (UIApplication.shared.delegate as? AppDelegate)?.coreDataStack.persistentContainer.viewContext {
let card = Card(context: context)
card.name = nameTextField.text
card.location = locationTextField.text
card.number = textField.text
if let image = imageView.image {
card.image = image.pngData()
}
do {
try context.save()
print("Cохранение удалось!")
} catch let error as NSError {
print("Не удалось сохранить данные \(error), \(error.userInfo)")
}
}
performSegue(withIdentifier: "unwindSegueFromNewCard", sender: self)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
imageView.image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
dismiss(animated: true, completion: nil)
}
}
ViewController2
import UIKit
class ViewController2: UIViewController {
var filter : CIFilter!
var delegate: ImageViewProtocol!
#IBOutlet weak var select: UISegmentedControl!
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var barcodeImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
barcodeImageView.image = UIImage(named: "photo")
}
#IBAction func saveButtonAction(_ sender: Any) {
if textField.text == "" {
print("Not all fields are filled")
} else {
delegate.sendImageToViewController(theImage: barcodeImageView.image!)
self.navigationController?.popViewController(animated: true)
}
performSegue(withIdentifier: "unwindSegueFromViewController", sender: sender)
}
#IBAction func tappedEnter(_ sender: Any) {
if textField.text?.isEmpty ?? true {
return
} else {
if let texttxt = textField.text {
let data = texttxt.data(using: .ascii, allowLossyConversion: false)
if select.selectedSegmentIndex == 0
{
filter = CIFilter(name: "CICode128BarcodeGenerator")
} else {
filter = CIFilter(name: "CIQRCodeGenerator")
}
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 5, y: 5)
let image = UIImage(ciImage: filter.outputImage!.transformed(by: transform))
barcodeImageView.image = image
}
}
}
}
This error comes because you implemented protocol (ImageViewProtcol) but you haven't add required methods of your protocol (in your case sendImageToViewController(theImage: UIImage)). All methods of your protocol are required by default. If you want to change it, you can look here.
It's the same as when you're implementing UITableViewDataSource, you also need to add required methods like number of items etc.
To fix this, add this method to your CardsViewController:
func sendImageToViewController(theImage: UIImage) {
// do something with image
}
I am currently trying to upload a photo URL and post caption onto my firebase database. The photos are currently being saved on firebase storage which is fine, however I would like for it to also appear on the firebase database.
I repeatedly find myself dealing with this error "Value of type 'StorageMetadata' has no member 'downloadURL'"
I understand that in firebase 5 to get the url from storage you need to call downloadURL on storage reference, not metadata. I have tried multiple ways and examples, but it all leads to errors.screenshot of error
#IBOutlet weak var photo: UIImageView!
#IBOutlet weak var captionTextView: UITextView!
#IBOutlet weak var removeButton: UIBarButtonItem!
#IBOutlet weak var shareButton: UIButton!
var selectedImage: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto)); photo.addGestureRecognizer(tapGesture)
photo.isUserInteractionEnabled = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
handlePost()
}
func handlePost() {
if selectedImage != nil {
self.shareButton.isEnabled = true
self.removeButton.isEnabled = true
self.shareButton.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
}else{
self.shareButton.isEnabled = false
self.shareButton.backgroundColor = .lightGray
self.removeButton.isEnabled = false
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
#objc func handleSelectPhoto() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
#IBAction func shareButton_TouchUpInside(_ sender: Any) {
view.endEditing(true)
let hud = JGProgressHUD(style: .dark)
hud.textLabel.text = "Loading"
hud.show(in: self.view)
hud.dismiss(afterDelay: 3.0)
if let profileImg = self.selectedImage, let imageData = UIImageJPEGRepresentation(profileImg, 0.1) {
let photoIdString = NSUUID().uuidString
let storageRef = Storage.storage().reference(forURL: ".......").child("posts").child(photoIdString)
storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
if error != nil {
return
}
//let photoUrl = url?.absoluteString
let photoUrl = metadata?.downloadURL()?.absoluteString
self.sendDataToDatabase(photoUrl: photoUrl!)
}
)}
}
#IBAction func remove_TouchUpInside(_ sender: Any) {
clean()
handlePost()
}
func sendDataToDatabase(photoUrl: String) {
let ref = Database.database().reference()
let postsReference = ref.child("posts")
let newPostId = postsReference.childByAutoId().key
let newPostReference = postsReference.child(newPostId)
newPostReference.setValue(["photoUrl": photoUrl, "caption": captionTextView.text!], withCompletionBlock: {
(error, ref) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
ProgressHUD.showSuccess("Success")
self.clean()
self.tabBarController?.selectedIndex = 0 // switches user back to selected tabbar 0 = first 1 = second etc.
})
}
func clean() {
self.captionTextView.text = ""
self.photo.image = UIImage(named:"placeholder-photo")
self.selectedImage = nil
}
}
extension CameraViewController: UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
print("did finish picking media")
if let image = info["UIImagePickerControllerOriginalImage"]
as? UIImage {
selectedImage = image
photo.image = image
}
// profileImage.image = infoPhoto
dismiss(animated: true, completion: nil)
}
}
import UIKit
import ProgressHUD
import FirebaseStorage
import FirebaseDatabase
class CameraViewController: UIViewController {
#IBOutlet weak var photo: UIImageView!
#IBOutlet weak var shareButton: UIButton!
#IBOutlet weak var captionTextView: UITextView!
#IBOutlet weak var removeButton: UIBarButtonItem!
var selectedImage: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto))
photo.addGestureRecognizer(tapGesture)
photo.isUserInteractionEnabled = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
handlePost()
}
func handlePost(){
if selectedImage != nil {
self.shareButton.isEnabled = true
self.removeButton.isEnabled = true
self.shareButton.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
} else {
self.shareButton.isEnabled = false
self.removeButton.isEnabled = false
self.shareButton.backgroundColor = .lightGray
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
#objc func handleSelectPhoto(){
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
// Share photos to the storage database
#IBAction func shareButton_TouchUpInside(_ sender: Any) {
view.endEditing(true)
ProgressHUD.show("Please wait...", interaction: false)
if let profileImg = self.selectedImage, let photoData = profileImg.jpegData(compressionQuality: 0.1) {
let photoIdString = NSUUID().uuidString
print(photoIdString)
let storageRef = Storage.storage().reference(forURL:Config.STORAGE_ROOT_REF).child("Posts").child(photoIdString)
storageRef.putData(photoData, metadata: nil, completion: { (metadata, error) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
let photoUrl = metadata?.downloadURL()?.absoluteString
self.sendDataToDatabase(photoUrl: photoUrl!)
})
} else {
ProgressHUD.showError("Profile image can't be empty")
}
}
#IBAction func remove_touchUpInside(_ sender: Any) {
clean()
handlePost()
}
func sendDataToDatabase(photoUrl:String){
let ref = Database.database().reference()
let postsReference = ref.child("posts")
let newPostId = postsReference.childByAutoId().key
let newPostReference = postsReference.child(newPostId)
newPostReference.setValue(["photoUrl": photoUrl, "caption": captionTextView.text!], withCompletionBlock: {
(error, ref) in
if error != nil{
ProgressHUD.showError(error!.localizedDescription)
return
}
ProgressHUD.showSuccess("Success")
self.clean()
self.tabBarController?.selectedIndex = 0
})
}
func clean(){
self.captionTextView.text = ""
self.photo.image = UIImage(named: "placeholder-img")
self.shareButton = nil
}
}
extension CameraViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
print("did Finish picking media")
if let chosenImage = info[.originalImage] as? UIImage {
selectedImage = chosenImage
photo.image = chosenImage
}
dismiss(animated: true, completion: nil)
}
}
Use Above code, it will successfully upload the image and post that to the Firebase Database
I need help here. I am trying to use core data to implement an app. But on line 52 -
myHood.setMyHoodImg(addHoodImg.image!))
I having an error each time a click the button to create a new hood. The error:
"Thread 1: EXC_BAD_ACCESS(Code=EXC_I386_GPFLT)
Here is the code:
import UIKit
import CoreData
class CreateHoodVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var hooddesc: UITextField!
#IBOutlet weak var addHoodImgBtn: UIButton!
#IBOutlet weak var addHoodImg: UIImageView!
var imagePicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
addHoodImg.layer.cornerRadius = 4.0
addHoodImg.clipsToBounds = true
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
imagePicker.dismissViewControllerAnimated(true, completion: nil)
addHoodImg.image = image
}
#IBAction func addImage(sender: AnyObject!){
presentViewController(imagePicker, animated: true, completion: nil)
}
#IBAction func createHood(){
if let hoodDescription = hooddesc.text where hoodDescription != ""{
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let entity = NSEntityDescription.entityForName("MyHood", inManagedObjectContext: context)!
let myHood = MyHood(entity: entity, insertIntoManagedObjectContext: context)
myHood.myHoodDescription = hoodDescription
myHood.setMyHoodImg(addHoodImg.image!)
context.insertObject(myHood)
do {
try context.save()
} catch {
print("Could not save new Hood")
}
}
}
}
it's really simple:
if You write:
myHood.setMyHoodImg(addHoodImg.image!)
you are supposing addHoodImg.image DOES exist, but on first run, is NIL, if You did not choose an image.
so 2 ways:
1) simply write:
if let hoodDescription = hooddesc.text where hoodDescription != "" , let img = addHoodImg.image {
2) disable button on start AND enable after choosing and image.
Hope this help.
ps I have a fully functional proto here with (reduced!) classes you use.