在解释响应之前,如何确保此功能完成?

时间:2017-02-03 07:25:18

标签: swift asynchronous completionhandler

我对Swift有点新鲜,并且在本网站的帮助下大部分都想知道如何使用完成处理程序。经过几天试图让它发挥作用,我感谢更多的直接帮助。

我有一个:

@IBAction func submitRegistrationButton(_ sender: Any) {

    if((firstNameField.text?.trimmingCharacters(in: .whitespacesAndNewlines).characters.count) == 0){
        showXAlert(title: "Oops!", message: "Please enter your first name.", viewController: self)
    }else if((lastNameField.text?.trimmingCharacters(in: .whitespacesAndNewlines).characters.count) == 0){
            showXAlert(title: "Oops!", message: "Please enter your last name.", viewController: self)
        }else if((emailAddressField.text?.trimmingCharacters(in: .whitespacesAndNewlines).characters.count) == 0){
                showXAlert(title: "Oops!", message: "Please enter your email address.", viewController: self)
            }else if !isValidEmail(testStr: emailAddressField.text!){
                    showXAlert(title: "Oops!", message: "Please enter a valid email address.", viewController: self)
                }else if((passwordField.text?.trimmingCharacters(in: .whitespacesAndNewlines).characters.count) == 0){
                    showXAlert(title: "Oops!", message: "Please enter a password.", viewController: self)
                    }else if passwordField.text != passwordConfirmationField.text{
                        showXAlert(title: "Oops!", message: "Your password and password confirmation do not match. Please correct.", viewController: self)
                }else{
                    registrant.firstName = firstNameField.text!
                    registrant.lastName = lastNameField.text!
                    registrant.zipCode = zipCodeField.text!
                    registrant.emailAddress = emailAddressField.text!
                    registrant.password = passwordField.text!
                    storeRegistrationInfo(registrant: registrant) { (object: XUserAPIResult) in

                        print("submissionStatus = \(object.success)")

                        if object.success == 1 {
                            showXAlert(title: "Welcome \(self.registrant.firstName)!", message: "Your registration was submitted successfully. Log in by clicking the Login button below", viewController: self)
                        }else{
                        showXAlert(title: "Un Oh", message: "There was a problem with your registration. \(object.errorMessage)", viewController: self)
                        }

                    }
                }
}

......打电话:

func storeRegistrationInfo(registrant: XRegistrantInfo, finished: @escaping (XUserAPIResult)->()) {
    var apiResult = XUserAPIResult()

    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let context = appDelegate.persistentContainer.viewContext

    let newRegistrant = NSEntityDescription.insertNewObject(forEntityName: "User", into: context)

    let requestURL = NSURL(string: USER_API_URL)
    let request = NSMutableURLRequest(url: requestURL! as URL)

    request.httpMethod = "POST"

    newRegistrant.setValue(registrant.firstName, forKey: "firstName")
    newRegistrant.setValue(registrant.lastName, forKey: "lastName")
    newRegistrant.setValue(registrant.zipCode, forKey: "zipCode")
    newRegistrant.setValue(registrant.emailAddress, forKey: "emailAddress")
    newRegistrant.setValue(registrant.password, forKey: "password")
    newRegistrant.setValue(registrant.personna, forKey: "personna")
    do{
        try context.save()
        let postParameters = "tag=" + REGISTRATION_API_TAG + "&firstName=" + registrant.firstName + "&lastName=" + registrant.lastName + "&password=" + registrant.password + "&username=" + registrant.emailAddress + "&personna=" + registrant.personna + "&zipCode=" + registrant.zipCode
        request.httpBody = postParameters.data(using: .utf8)
        let task = URLSession.shared.dataTask(with: request as URLRequest){
            data, response, error in

            if error != nil{
                print("error is \(error)")
                return
            }

            print("response = \(response)")
            //parsing the response
            do {
                //converting resonse to NSDictionary
                let myJSON =  try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

                //parse json 2

                if let dictionary = myJSON as? [String: Any]{
                    if let apiSuccess = dictionary["success"] as? Int{
                        apiResult.success = apiSuccess
                    }
                    if let apiError = dictionary["error"] as? Int{
                        apiResult.error = apiError
                        if apiError != 0{
                            if let apiErrorMessage = dictionary["error_msg"] as? String{
                                apiResult.errorMessage = apiErrorMessage
                            }

                        }else{
                            if let apiUID = dictionary["uid"] as? String{
                                apiResult.uniqueID = apiUID
                            }
                            if let nestedDictionary = dictionary["user"] as? [String: Any]{
                                if let apiFirstName = nestedDictionary["firstName"] as? String{
                                    apiResult.user.firstName = apiFirstName
                                }
                                if let apiLastName = nestedDictionary["lastName"] as? String{
                                    apiResult.user.lastName = apiLastName
                                }
                                if let apiEmail = nestedDictionary["e-mail"] as? String{
                                    apiResult.user.emailAddress = apiEmail
                                }
                                if let apiCreatedAt = nestedDictionary["created_at"] as? String{
                                    apiResult.user.createdAt = apiCreatedAt
                                }
                                if let apiPersonna = nestedDictionary["personna"] as? String{
                                    apiResult.user.personna = apiPersonna
                                }
                            }
                            finished(apiResult)
                        }
                    }
                }
            } catch {
                print(error)
            }
        }
        task.resume()
        finished(apiResult)
    } catch {
        print("There was an error saving to Core Data")
        finished(apiResult)
    }
}

submitRegistrationButton()代码应该等到 storeRegistrationInfo()返回 XUserAPIResult结构,然后根据<显示相应的警告strong> XUserAPIResult 的成功属性。

问题是成功检查代码是在 storeRegistrationInfo()完成解析JSON之前执行的;显示错误的警报,然后在解析JSON后正确执行。代码的其他方面(Web API调用,解析JSON,将数据保存到Web数据库)有效。

我很确定我如何使用完成处理程序或调用storeRegistrationInfo(),但我不确定如何修复它。

如何确保 @IBAction func submitRegistrationButton(_ sender:Any)中的警报代码:

storeRegistrationInfo(registrant: registrant) { (object: XUserAPIResult) in

   print("submissionStatus = \(object.success)")

   if object.success == 1 {
      showXAlert(title: "Welcome \(self.registrant.firstName)!", message: "Your registration was submitted successfully. Log in by clicking the Login button below", viewController: self)
   }else{
      showXAlert(title: "Un Oh", message: "There was a problem with your registration. \(object.errorMessage)", viewController: self)
   }    
}

...仅在解析JSON并填充并传回UserAPIResult结构后调用?

感谢。

2 个答案:

答案 0 :(得分:0)

尝试以下

typealias CompletionHandler = (data:XRegistrantInfo,success:Bool) -> Void;


func storeRegistrationInfo(registrant: XRegistrantInfo,completionHandler: CompletionHandler) {
    // your  code.
    //
    //
    completionHandler(data: dataToReturn,success : true/false)
}

呼叫将是

storeRegistrationInfo(registrant, { (data,success) -> Void in
    //onCompletion the code will go here
    if success {
        // success
    } else {
        // fail
    }
})

答案 1 :(得分:0)

代码中的问题就在这里:

task.resume()
finished(apiResult)

你应该删除对finished完成处理程序的调用,因为在获得响应后,应该在放置它的位置调用它。

另一项改进建议是简化字段验证码以使用guard语句。