代码之家  ›  专栏  ›  技术社区  ›  Renan Aguiar

等待任务在会话上返回。数据任务

  •  0
  • Renan Aguiar  · 技术社区  · 8 年前

    我有一个项目,在这个项目中,我从API发送和获取数据。发送和获取它工作正常。

    我的目标是等待服务器的响应(即:是|否),并根据它的情况,继续或不继续该序列,如果否,则显示警报。

    对于这一部分,我有:

    1. 具有客户端列表和用于添加新客户端的按钮的tableview视图。
    2. 添加/编辑客户端的详细视图
    3. 在详细视图上有一个保存按钮,该按钮与tableview视图相连

    功能 saveClient() 获取数据并向服务器发出请求

    func saveClient() -> Bool {
    
        let name = txtName.text ?? ""
        let address = txtAddress.text ?? ""
        let city = txtCity.text ?? ""
        let province = txtProvince.text ?? ""
        let postal_code = txtPostalCode.text ?? ""
    
        meal = Client(name:name, client_id: "", postal_code: postal_code, province: province, city: city, address: address)
    
        var jsonData = Data()
        let jsonEncoder = JSONEncoder()
        do {
            jsonData = try jsonEncoder.encode(meal)
        }
        catch {
        }
        print("a1")
        var success: Bool
        success = false
    
        makeRequestPost(endpoint: "http://blog.local:4711/api/clients/add",
                        requestType: "POST",
                        requestBody: jsonData,
                        completionHandler: { (response : ApiContainer<Client>?, error : Error?) in
                            if let error = error {
                                print("error calling POST on /todos")
                                print(error)
                                return
                            }
                            let b = (response?.meta)!
                            print(b.sucess)
                            if(b.sucess == "yes") {
                                success = true
                            }
                            else
                            {
                                DispatchQueue.main.async(execute: {
                                    let myAlert = UIAlertController(title: "Error", message: "Error creating Client", preferredStyle: .alert)
                                    let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
                                    myAlert.addAction(okAction)
                                    self.present(myAlert, animated: true, completion: nil)
                                })
                                return
                            }
        } )
        return success
    }
    

    在同一控制器上:

    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    
        guard let button = sender as? UIBarButtonItem, button === btnSave else {
            return false
        }
    
        if !saveClient() {
            print("no sir")
            return false
        }
    
        print("yes sir")
        return true
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)        
        guard let button = sender as? UIBarButtonItem, button === btnSave else {
            return
        }
    }
    

    请求功能:

    func makeRequestPost<T>(endpoint: String,
                         requestType: String = "GET",
                         requestBody: Data,  completionHandler: @escaping (ApiContainer<T>?, Error?) -> ()) {
    
        guard let url = URL(string: endpoint) else {
            print("Error: cannot create URL")
            let error = BackendError.urlError(reason: "Could not create URL")
            completionHandler(nil, error)
            return
        }
    
        var urlRequest = URLRequest(url: url)
        let session = URLSession.shared
    
        urlRequest.httpMethod = "POST"
        urlRequest.httpBody = requestBody
    
        urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
        urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
    
    
    
        let task = session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            guard let responseData = data else {
                print("Error: did not receive data")
                completionHandler(nil, error)
                return
            }
            guard error == nil else {
                completionHandler(nil, error!)
                return
            }
    
            do {
                let response = try JSONDecoder().decode(ApiContainer<T>.self, from: responseData)
                completionHandler(response, nil)
            }
            catch {
                print("error trying to convert data to JSON")
                print(error)
                completionHandler(nil, error)
            }
    
        })
        task.resume()
    }
    

    在控制台上,我得到:

    a1级

    没有,先生

    正确的答案是:

    a1级

    是的,先生

    最终注释:

    1. 我尝试了一些信号量的例子。。。但它没有起作用。

    2. 我在其他地方使用了一个名为“Dine”的var,并没有将其更改为客户端。但是,它不会干扰代码的这一部分

    1 回复  |  直到 8 年前
        1
  •  0
  •   Rob Md Fahim Faez Abir    8 年前

    你说:

    我的目标是等待来自服务器的响应(即:是|否),并根据它的情况,继续或不继续

    虽然我理解这种方法的自然吸引力,但现实是你永远不应该“等待”(尤其是在 shouldPerformSegue ). 您的UI将冻结(如果用户的互联网连接不良,尤其值得注意),您的应用程序很容易被查找冻结应用程序的监视器进程杀死,等等。

    因此,与其表演segue shouldPerformSegue公司 尝试等待网络响应以查看是否可以继续,换一种方式进行:您可以编写执行查询的代码,如果一切正常,则只需以编程方式启动segue。

    推荐文章