私はSwiftに若干新しく、このサイトの助けを借りて補完ハンドラを使用する方法をほとんど考え出しました。数日後にこれを動作させると、より直接的な助けに感謝します。 XUserAPIResult構造体を返すレスポンスを解釈する前に、この関数が完了していることを確認するにはどうすればよいですか?
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(まで待つことになっている):
@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)
}
}
}
}
...呼び出すこと:私が持っている
を入力し、に基づいて適切なアラートを表示します。XUserAPIResult's成功プロパティ。
問題は、成功チェックコードが実行されてからstoreRegistrationInfo()がJSONの解析を完了する前に実行されていることです。間違ったアラートを表示し、JSONが解析された後に正しく実行されます。コードの他の側面(Web API呼び出し、JSONの解析、Webデータベースへのデータの保存)は機能します。
私は、補完ハンドラの使用方法やstoreRegistrationInfo()の呼び出し方法に問題がありますが、修正方法はわかりません。:JSONを解析された後
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)
}
}
...だけと呼ばれ、UserAPIResult構造体は次のとおりです。
は、どのように私は@IBActionのFUNCのsubmitRegistrationButtonでアラートコード(どれ_送信者が)ことを確認してください人口は移住し、戻った?
ありがとうございました。
ありがとう!それはそれを修正したようだ!私はガードステートメントに関するあなたの助言に従います... – Wayne
...「ようこそ...」アラートが表示された後、アプリケーションがクラッシュしているため、上記のように表示されます。これが関連しているかどうかはわかりません。 – Wayne
この問題と、同じ問題に遭遇した他の人のために、[this thread](http://stackoverflow.com/questions/37801370/how-do-i-dispatch-sync-dispatch-async-dispatch)のおかげで-after-etc-in-swift-3) 'showXAlert()'が主なスレッド以外のスレッドから警告を提示しようとしていることに気付きました。これがクラッシュを引き起こしていたものです。 – Wayne