【问题标题】:Implementing Completion Block swift快速实现完成块
【发布时间】:2018-07-11 02:00:41
【问题描述】:

我已经实现了一个有逻辑错误的完成块。我希望在单击 checkOutBtn 时首先触发 checkFields 以检查所有文本字段是否不为空,然后再触发 addDeliveryAddress() 方法插入数据库,然后再执行 sesueway。但是当点击 checkOutBtn 时它不会那样工作,它会继续执行 segueway。感谢你的帮助。谢谢

   @IBAction func checkOutBtn(_ sender: Any) {

    checkFields { (results) in
        if results {
            self.addingDeliveryAddress()
        }
    }
}


func checkFields(_ completion: @escaping (Bool) -> ()){
        if (recipientName.text?.isEmpty)! {
            errorMessageLbl.textColor = UIColor.red
            errorMessageLbl.text = "Enter Recipient Name"
            completion(false)
        }else if (recipientMobile.text?.isEmpty)! {
            errorMessageLbl.textColor = UIColor.red
            errorMessageLbl.text = "Enter Recipient Mobile Number"
            completion(false)
        }else if (recipientArea.text?.isEmpty)! {
            errorMessageLbl.textColor = UIColor.red
            errorMessageLbl.text = "Enter Recipient Area"
            completion(false)
        }else if (recipientAddress.text?.isEmpty)! {
            errorMessageLbl.textColor = UIColor.red
            errorMessageLbl.text = "Enter Recipient Address"
            completion(false)
        }
        completion(true)
    }



    //Adding Delivery Address
    func addingDeliveryAddress(){

        //getting user data from defaults
        let defaultValues = UserDefaults.standard
        let userId = defaultValues.string(forKey: "userid")

        //creating parameters for the post request
        let parameters: Parameters=[
            "recipientName":recipientName.text!,
            "recipientPhoneNumber":recipientMobile.text!,
            "recipientArea":recipientArea.text!,
            "recipientAddress":recipientAddress.text!,
            "nearestLandmark":recipientLandmark.text!,
            "userId":Int(userId!)!
        ]

        //Constant that holds the URL for web service
        let URL_ADD_DELIVERY_ADDRESS = "http://localhost:8888/restaurant/addDeliveryAddress.php?"

        Alamofire.request(URL_ADD_DELIVERY_ADDRESS, method: .post, parameters: parameters).responseJSON {
            response in
            //printing response
            print(response)

            let result = response.result.value

            //converting it as NSDictionary
            let jsonData = result as! NSDictionary

            //if there is no error
            if(!(jsonData.value(forKey: "error") as! Bool)){

                self.performSegue(withIdentifier: "toCheckOut", sender: self)

            }else{

                let alert = UIAlertController(title: "No Delivery Address", message: "Enter Delivery Address to continue", preferredStyle: .alert)

                alert.addAction(UIAlertAction(title: "Ok", style: .destructive, handler: nil))
                //alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: nil))

                self.present(alert, animated: true)
            }
        }
    }

【问题讨论】:

    标签: swift


    【解决方案1】:

    为什么是完成块?没有异步进程。

    我建议这种方式在成功时(直接)返回错误字符串或空字符串。

    @IBAction func checkOutBtn(_ sender: Any) {
    
        let result = checkFields()
        if result.isEmpty {
            self.addingDeliveryAddress()
        } else {
           errorMessageLbl.textColor = UIColor.red
           errorMessageLbl.text = "Enter Recipient " + result
        }
    }
    
    func checkFields() -> String {
        if recipientName.text!.isEmpty {
            return "Name"
        } else if recipientMobile.text!.isEmpty {
            return "Mobile Number"
        } else if recipientArea.text!.isEmpty {
            return "Area"
        } else if recipientAddress.text!.isEmpty {
            return "Address"
        }
        return ""
    }
    

    【讨论】:

      【解决方案2】:

      在您的代码中,您在闭包中使用了 @escaping。这是错误的,因为您没有在这个闭包主体中做任何异步操作。当使用 @escaping 时,闭包被保留以供稍后执行,并且函数的主体被执行。这就是为什么在检查任何内容之前触发 addingDeliveryAddress() 的原因。你的闭包函数应该是 @nonescaping 像这样..

      func checkFields(_ completion: (Bool) -> ()){
              if (recipientName.text?.isEmpty)! {
                  errorMessageLbl.textColor = UIColor.red
                  errorMessageLbl.text = "Enter Recipient Name"
                  completion(false)
              }else if (recipientMobile.text?.isEmpty)! {
                  errorMessageLbl.textColor = UIColor.red
                  errorMessageLbl.text = "Enter Recipient Mobile Number"
                  completion(false)
              }else if (recipientArea.text?.isEmpty)! {
                  errorMessageLbl.textColor = UIColor.red
                  errorMessageLbl.text = "Enter Recipient Area"
                  completion(false)
              }else if (recipientAddress.text?.isEmpty)! {
                  errorMessageLbl.textColor = UIColor.red
                  errorMessageLbl.text = "Enter Recipient Address"
                  completion(false)
              }
              completion(true)
          }
      

      【讨论】:

      • 谢谢,但我已经意识到我的错误了。你的解决方案很好,但我认为@vadian 的建议是最好的,因为我只设置 textColor 并且只有在验证失败时才设置,所以他的代码很好而且整洁
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多