对服务器的 POST 请求后,用户对象包含 nil

Posted

技术标签:

【中文标题】对服务器的 POST 请求后,用户对象包含 nil【英文标题】:User object contains nil after POST request to server 【发布时间】:2019-03-26 05:12:00 【问题描述】:

使用 alamofire 发送 POST 请求以在我的应用程序中注册用户后,我试图从服务器返回的 user_id 创建一个用户对象。但是,当我尝试在初始化后直接打印此用户对象的某些属性时,它可以正常工作。但是,当我在 alamofire 发布请求完成执行后尝试打印它的一些属性时,我得到了 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
        
    


【问题讨论】:

先执行Segue 调用,然后在完成块调用之后。您必须将 segue 代码添加到成功案例中。 switch response.result 行之前添加print("Alamofire Completion")。你会看到print(self.user?.name) 的输出顺序,而那个不是你想的那个。您缺少异步概念。 【参考方案1】:

您的服务调用是异步的。了解同步与异步方法。

Medium

Ray Wenderlich

AF 向服务器发送请求,下面的代码继续工作。当您的响应到达时,successfailure 块开始工作。

所以在成功块运行之前不会分配用户对象。

这里是解决方案:

 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")
    

您可以在等待请求响应的同时在页面中显示加载,并在成功时隐藏它。

【讨论】:

以上是关于对服务器的 POST 请求后,用户对象包含 nil的主要内容,如果未能解决你的问题,请参考以下文章

编码请求主体

为啥我在尝试在 iOS Swift 中向服务器发出 post 请求时收到此错误:在展开 Optional 值时意外发现 nil?

alamofire:带有标头的 POST 请求

如何在 node.js 中处理 POST 请求

对 Wordpress REST API 的 POST 请求返回一个空对象

POST 请求后删除 CoreData 对象