URL, возвращающийся из хранилища Firebase - ноль Swift4 - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь загрузить изображение в хранилище Firebase и получить URL-адрес загрузки, чтобы сохранить его в базе данных, но я получаю нулевое значение, и функция возвращает его после проверки. Я следил за документацией и решениями из других постов, и я не вижу, где я ошибаюсь. Функция:

func uploadImage(completed: @escaping (Bool) -> (),_ image: UIImage ){
        print("      ##############         UPLOAD STARTED         ###########")

        //        let stringURL: String?
//        guard let uid = Auth.auth().currentUser?.uid else {return} // use the userUid to sign the alert


        // Create a root reference
        let storageRef = Storage.storage().reference()

        // Create a reference to "mountains.jpg"
//        let alertsRef = storageRef.child("userAlertImages.jpg")//("user/\(uid)") // change path for userAlertImages path

        // Create a reference to 'images/mountains.jpg'
        let alertsImagesRef = storageRef.child("Alert Images/userAlertImages.jpg")

        // While the file names are the same, the references point to different files
//        alertsRef.name == alertsImagesRef.name;            // true
//        alertsRef.fullPath == alertsImagesRef.fullPath;    // false


        let imageData = UIImageJPEGRepresentation(image, 0.5)

        let metaData = StorageMetadata()
        metaData.contentType = " jpeg " // data type
        metaData.customMetadata = ["k1": "",
                                   "k2" : " ",
                                   "k3" : "",
                                   "k4" : ""]

        alertsImagesRef.putData(imageData! as Data , metadata: metaData) { metaData, error in
            if(error != nil){
                print(error as Any)
                return
            }
        }

        // Fetch the download URL
        alertsImagesRef.downloadURL { (url,error) in
            guard let downloadURL = url else {
                print("@@@@@@@@@@ downloaded url is: \(url)  @@@@@@@@@@@@@")
                return
            }
            NewMapViewController.alertImageURL = (url?.absoluteString) ?? ""
//            NewMapViewController.alertImageURL = (downloadURL)

            print("######### url is:\(String(describing: url)) #########")
            completed(true)
            //                            self.postAlertNotification()
            self.tapCounter = 0
            self.performSegue(withIdentifier: "chooseIconSegue", sender: self)

        }

}

Вы видите, где ошибка? Большое спасибо.

1 Ответ

0 голосов
/ 26 марта 2019

Думая об этом, я понял, что downloadURL выборка была фактически сделана раньше, чем загрузка изображения была завершена, потому что Firebase асинхронный.Поэтому я добавил completion block к части загрузки, а в completion scope я добавил downloadURL извлекающую часть.Это не моргание глаз быстро, и я буду признателен за любые предложения по ускорению вещей, потому что таким образом есть небольшая задержка, прежде чем будет выполнено segue.Это совсем не раздражает, и я мог бы, и, вероятно, должен добавить небольшое вращающееся колесо, чтобы показать пользователям, что приложение не зависло, но я, скорее всего, просто избегаю задержки.Я оставил prints написанным в надежде, что этот пост поможет другим новичкам в Firebase, как и я, давая подробное, почти пошаговое руководство, так как подобные ответы действительно помогли мне раньше, и я не нашел ни одного напредмет.Переписанная функция:

func uploadImage(completed: @escaping (Bool) -> (),_ image: UIImage ){
        print("      ##############         UPLOAD STARTED         ###########")

        // Create a root reference
        let storageRef = Storage.storage().reference()


        // Create a reference to Images folder
        let alertsImagesRef = storageRef.child("Alert Images")
        // Create a reference for new images
        let uuid = UUID()
        let imageRef = alertsImagesRef.child("userAlertImage \(uuid).jpg")

        let imageData = UIImageJPEGRepresentation(image, 0.5)

        let metaData = StorageMetadata()
        metaData.contentType = " jpeg " // data type
        metaData.customMetadata = ["k1": "",
                                   "k2" : " ",
                                   "k3" : "",
                                   "k4" : ""]

        imageRef.putData(imageData! as Data , metadata: metaData, completion: { metaData, error in
            if(error != nil){
                print(error as Any)
                return
            }
            print("               ####### image uploaded #######")
            self.tapCounter = 0
            self.performSegue(withIdentifier: "chooseIconSegue", sender: self)
            // fetch url v2
            imageRef.downloadURL(completion: { (url, err) in
                if let err = err {
                    print("Error downloading image file, \(err.localizedDescription)")
                    return
                }

                guard let url = url else { return }
                //Now you have the download URL for the image, and can do whatever you want with it.
                NewMapViewController.alertImageURL = url.absoluteString

                print("       ######### url is:\(String(describing: url)) #########")
                completed(true)
                //                            self.postAlertNotification()
//                self.tapCounter = 0
//                self.performSegue(withIdentifier: "chooseIconSegue", sender: self)
                print("      ##############         UPLOAD ENDED         ###########")
            })
        })
    }
...