简体   繁体   中英

User object contains nil after POST request to server

After sending a POST request using alamofire to register a user in my app, I am attempting to create a User object from the returned user_id from my server. However, when I attempt to print some attributes of this user object directly after I initialize it, it works fine. However, when I try and print some attributes of it after the alamofire post request has finished executing, I am getting nil.

import UIKit
import Alamofire

class ViewController: UIViewController {
    var user: User!
    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var emailField: UITextField!
    @IBOutlet weak var phone_number_field: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }
    //MARK: Actions
    @IBAction func generateQR(_ sender: UIButton) {
        let name = nameField.text
        let email = emailField.text
        let phone_number = phone_number_field.text
        let params: Parameters = ["name": name!, "email": email!, "phone_number": phone_number!]
        AF.request("http://127.0.0.1:5000/register", method: .post, parameters: params, encoding: JSONEncoding.default).responseString { response in
                switch response.result {
                case .success:
                    let user_id = response.result.value
                    self.user = User(name: name!, email: email!, phone_number: phone_number!, user_id: user_id!)
                    print(self.user?.name) // <--This print statement works correctly -->
                case .failure:
                    print("Error")
            }
        }
        print(self.user?.name) // <--This prints nil and in the debugger, self.user shows as nil--> 
        performSegue(withIdentifier: "qrSegue", sender: self)
    }

    //END Actions

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.destination is QRCodeController {
            //Pass user object
            let qr_controller = segue.destination as? QRCodeController
            qr_controller?.user = self.user
        }
    }

}

Your service call is async. Read about sync vs async methods.

Medium

Ray Wenderlich

AF sent request to the server and codes below continues working. When your response will arrive then success or failure blocks start working.

So the user object is not assigned until the success block is running.

Here is solution:

 AF.request("http://127.0.0.1:5000/register", method: .post, parameters: params, encoding: JSONEncoding.default).responseString { response in
    switch response.result {
        case .success:
            let user_id = response.result.value
            self.user = User(name: name!, email: email!, phone_number: phone_number!, user_id: user_id!)

            print(self.user?.name) // <--This print statement works correctly -->
            performSegue(withIdentifier: "qrSegue", sender: self)

        case .failure:
            print("Error")
    }
}

And you can show loading in your page while pending response from request and hide it on success.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM