为什么 .putData 不使用 Swift 在 Firebase 存储中上传图像?

Why .putData does not upload Image in Firebase Storage with Swift?

我有一个简单的 swift 应用程序,用户可以在其中从图库中选择一张图片,此外还可以输入一些数据。通过单击“保存”,所选图像应上传到 Firestore 存储中。 我实现了此处描述的相同逻辑 https://firebase.google.com/docs/storage/ios/upload-files。当我调用“.putData(data, metadata: nil)”时,什么也没有发生,也没有返回任何错误。这是代码片段:

    func uploadImage(imageView: UIImageView) -> String {

        // Variable for my image url
        var urlString: String
        urlString = ""

        storage = Storage.storage()

        guard let image = imageView.image,
            let imageData = image.jpegData(compressionQuality: 1.0) else {
                print ("no image uploaded")
                return ""
        }
        let imageName = String (Int64((NSDate().timeIntervalSince1970 * 1000.0).rounded())) + ".jpg"
        let imageRef = storage.reference().child(Constants.IMAGES_PATH).child(imageName)

        // QUOTE : THIS PART DOES NOT GIVE ANY FEEDBACK. NONE OF THE PRINTS INSIDE IT IS EXECUTED
        let uploadTask = imageRef.putData(imageData, metadata: nil) { (metadata, error) in
          if let error = error {
            // Uh-oh, an error occurred!
            print(error)
            return
          }
          imageRef.downloadURL { (url, error) in
            guard let downloadURL = url else {
              print ("error")
              return
            }
            urlString = downloadURL.absoluteString
            print("Downloaded image URL ", urlString)
          }
        }
        // UNQUOTE

        print ("after uploadTask", imageRef.downloadURL) // THE URL IS ALWAYS EMPTY ""

        return urlString

    }

我设置了一个调试器断点,显示uploadTask里面的代码没有执行,只执行了uploadTask,里面的一切都被跳过了。

像这样选择图片后调用uploadImage函数:

        var image = uploadImage(imageView: imageView)

图像是在这里选择的(这很好用):

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            imageView.contentMode = .scaleAspectFit
            imageView.image = pickedImage
            print("image chosen")
        }

        dismiss(animated: true, completion: nil)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }

我是这样初始化的,应该没问题:

import UIKit
import os.log
import FirebaseFirestore
import Firebase

class DisplayMediumViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    var storage: Storage!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Additional setup after loading the view.
        imagePicker.delegate = self

        // Create tap gesture recognizer
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(DisplayMediumViewController.imageTapped(gesture:)))

        // Aadd it to the image view;
        imageView.addGestureRecognizer(tapGesture)

        // Make sure imageView can be interacted with by user
        imageView.isUserInteractionEnabled = true


    }


我在网上搜索了很多,尝试了不同的实现方式,none成功了。如果有人提示为什么 "uploadTask = imageRef.putData" 不上传图像也不 return 任何下载 URL,那就太好了。

putData是一个带有回调函数的异步调用。 print 和 return 在 putData 有机会 return.

之前执行

如果您在 if let error = error 处放置一个断点,您应该能够看到结果。

查看类似 question/answer