【问题标题】:How to work with async functions swift? Completion handlers [duplicate]如何快速使用异步函数?完成处理程序[重复]
【发布时间】:2017-11-12 22:45:14
【问题描述】:

我试图等待函数处理以显示我的图像。我尝试了很多东西,但没有一个奏效。我知道这是一个异步函数,基本上我必须等待才能获得正确的值,但我不知道如何在这里修复这个函数。我希望你能帮助我。谢谢!

     func createListProductsGood(Finished() -> void) {

        refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: { snapshot in

            let prod = snapshot.value as! NSDictionary
            let active = snapshot.key
            let rejected = prod["NotInterested"] as! String
            let photoURL = prod["photoURL"] as! String
            var findit = false

           // print(rejected)

            if (rejected != self.userUID){
                //print(active)
                if rejected.contains(","){
                     var pointsArr = rejected.components(separatedBy: ",")
                        for x in pointsArr{
                                if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID {
                                   // print("dont show")
                                    findit = true
                                    return
                                }
                            }

                    if (findit == false){
                        if let url = NSURL(string: photoURL) {
                            if let data = NSData(contentsOf: url as URL) {
                                self.ProductId = active
                                self.productPhoto.image = UIImage(data: data as Data)
                            }}
                    }
                }else{
                    print(active)
                    if let url = NSURL(string: photoURL) {
                        if let data = NSData(contentsOf: url as URL) {
                            self.ProductId = active
                            self.productPhoto.image = UIImage(data: data as Data)

                        }}
                }


            }

               })

    finished()

}

已编辑:

这就是我的 viewDidLoad 的样子:

override func viewDidLoad() {
    super.viewDidLoad()
    setAcceptedOrRejected()
    createListProductsGood{_ in
    }


}



 func createListProductsGood(finished: @escaping (_ imageData: Data) -> Void) {

        refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: { snapshot in

            let prod = snapshot.value as! NSDictionary
            let active = snapshot.key
            let rejected = prod["NotInterested"] as! String
            let photoURL = prod["photoURL"] as! String
            var findit = false

           // print(rejected)

            if (rejected != self.userUID){
                //print(active)
                if rejected.contains(","){
                     var pointsArr = rejected.components(separatedBy: ",")
                        for x in pointsArr{
                                if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID {
                                   // print("dont show")
                                    findit = true
                                    return
                                }
                            }

                    if (findit == false){
                        if let url = NSURL(string: photoURL) {
                            if let data = NSData(contentsOf: url as URL) {
                                self.ProductId = active
                                DispatchQueue.main.async {
                                    self.productPhoto.image = UIImage(data: data as Data)
                                }
                            }}
                    }
                }else{
                    print(active)
                    if let url = NSURL(string: photoURL) {
                        if let data = NSData(contentsOf: url as URL) {
                            self.ProductId = active
                            DispatchQueue.main.async {
                             self.productPhoto.image = UIImage(data: data as Data)
                            }
                        }}
                }
        }
             })

}

这是我的第二种方法:

func setAcceptedOrRejected() {
    refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: { snapshot in

        let prod = snapshot.value as! NSDictionary

        if self.ProductId == snapshot.key{

            self.texto = prod["NotInterested"] as! String
            self.refProducts.child("Products").child(self.ProductId).updateChildValues(["NotInterested": self.texto + ", " + self.userUID])

        } })
}

【问题讨论】:

    标签: swift firebase asynchronous completionhandler


    【解决方案1】:

    你应该改变:

    func createListProductsGood(Finished() -> void) {
    

    到:

    func createListProductsGood(finished: @escaping (_ something: SomeType) -> Void) {
    

    或者更具体一点:

    func createListProductsGood(finished: @escaping (_ imageData: Data) -> Void) {
    

    然后,无论您在函数中获得图像的任何位置,调用

    finished(imageData)
    

    这样您就可以通过 闭包 将 imageData 传递 到需要的地方。

    然后你像这样调用这个函数:

    createListProductsGood{ imageData in 
        ...
       let image = UIImage(data: imageData)
    
       // update UI from main Thread:
       DispatchQueue.main.async {
       self.productPhoto.image = image
       }
    }
    

    还有:

    • 不习惯使用Finished(),你应该使用finished()

    • 使用void 是错误的。您必须使用Void()


    如果您在使用闭包和完成处理程序时遇到问题,我建议您首先尝试使用简单的 UIAlertController。见here。尝试使用闭包创建一个动作,例如见here


    编辑:

    感谢 Leo 的 cmets:

    func createListProductsGood(finished: @escaping(_ imageData: Data?, MyError?) -> Void) {
    
    let value: Data?
    let error = MyError.someError("The error message")
    
        refProducts.child("Products").queryOrderedByKey().observe(.childAdded, with: { snapshot in
    
            let prod = snapshot.value as! NSDictionary
            let active = snapshot.key
            let rejected = prod["NotInterested"] as! String
            let photoURL = prod["photoURL"] as! String
            var findit = false
    
            // print(rejected)
    
            if (rejected != self.userUID){
                //print(active)
                if rejected.contains(","){
                    var pointsArr = rejected.components(separatedBy: ",")
                    for x in pointsArr{
                        if x.trimmingCharacters(in: NSCharacterSet.whitespaces) == self.userUID {
                            // print("dont show")
                            findit = true
                            return
                        }
                    }
    
                    if (findit == false){
                        if let url = NSURL(string: photoURL) {
                            if let data = NSData(contentsOf: url as URL) {
                                self.ProductId = active // REMOVE
                                self.productPhoto.image = UIImage(data: data as Data) // REMOVE
                                finished(data, nil) //ADD
                            }else{
                                finished(nil,error) //ADD
                            }
                        }
                    }
                }else{
                    print(active)
                    if let url = NSURL(string: photoURL) {
                        if let data = NSData(contentsOf: url as URL) {
                            self.ProductId = active // REMOVE
                            self.productPhoto.image = UIImage(data: data as Data) // REMOVE
                            finished(data,nil) //ADD
                        }else{
                            finished(nil,error) //ADD
                        }
                    }
                }
    
            }
        })
    }
    

    然后你这样称呼它:

       createListProductsGood { imageData, error in guard let value = imageData, error == nil else { // present an alert and pass the error message return } 
    
       ...
       let image = UIImage(data: imageData)
    
       // update UI from main Thread:
       DispatchQueue.main.async { 
       self.ProductId = active
    
       self.productPhoto.image = image } }
    

    基本上这种方式createListProductsGood 接受2 个闭包,一个用于如果图像存在,另一个用于如果返回错误。

    【讨论】:

      猜你喜欢
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多