Ich bin Swift etwas neu und habe meistens herausgefunden, wie man mit Hilfe dieser Seite die Vervollständigungshandler benutzt. Nach einigen Tagen, in denen ich versuchen würde, dies zur Arbeit zu bringen, würde ich mir mehr direkte Hilfe wünschen.Wie kann ich sicherstellen, dass diese Funktion abgeschlossen ist, bevor ich die Antwort interpretiere?
Ich habe ein:
@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)
}
}
}
}
... das nennt:
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)
}
}
Die submitRegistrationButton() Code soll bis storeRegistrationInfo warten() eine XUserAPIResult kehrt struct und dann den entsprechenden Alarm basierend auf XUserAPIResult anzeigen Erfolgseigenschaft.
Das Problem besteht darin, dass der Erfolgsprüfungscode ausgeführt wird, bevor storeRegistrationInfo() die JSON-Analyse abschließt; Anzeige der falschen Warnung und dann korrekt ausgeführt, nachdem der JSON analysiert wurde. Die anderen Aspekte des Codes (der Web-API-Aufruf, das Parsen des JSON, das Speichern der Daten in der Web-Datenbank) funktionieren.
Ich bin mir ziemlich sicher, dass etwas falsch ist mit, wie ich den Abschluss-Handler oder den Aufruf von storeRegistrationInfo(), aber ich bin mir nicht sicher, wie genau es zu beheben.
Wie kann ich sicherstellen, dass der Alarm Code in @IBAction func submitRegistrationButton (_ Absender: 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)
}
}
... erst nach dem JSON analysiert wird aufgerufen und die UserAPIResult Struktur ist bevölkert und zurückgegeben?
Danke.
Danke! Das scheint es behoben zu haben! Ich werde Ihrem Rat bezüglich der Wächterstatements folgen ... – Wayne
... Ich sage "scheint" oben, weil die App jetzt abstürzt, nachdem die Warnung "Willkommen ..." angezeigt wird.Ich weiß nicht, ob das zusammenhängt. – Wayne
Um diese Frage und für jeden anderen, der das gleiche Problem hat, zu schließen, dank [diesem Thread] (http://stackoverflow.com/questions/37801370/how-do-i-dispatch-sync-dispatch-async-dispatch -after-etc-in-swift-3) Ich erkannte, dass 'showXAlert()' versuchte, die Warnung von einem anderen Thread als dem Haupt-Thread zu präsentieren. Das hat den Absturz verursacht. – Wayne