我对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结构后调用?
感谢。
答案 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
语句。