如何将数据从异步任务传递到视图控制器?

时间:2017-06-03 17:07:52

标签: ios swift asynchronous

摘要

我在异步任务中使用用户的登录用户名和密码查询用户的API。我找到了一种方法:

  1. 在与我的UIViewController相同的文件中创建协议委托。
  2. 使协议委托UIViewController的成员。
  3. 创建用于执行异步的API类。任务。
  4. 定义UIViewController的委托成员变量的完成处理函数。
  5. 将URL,委托,参数等传递给API类。
  6. 执行异步。 API类中的任务。
  7. 一旦异步。任务完成后,完成处理程序在原始视图控制器中执行。
  8. API文件

    class API {
        var delegate: APIDelegate?
        required init(providedDelegate: APIDelegate){
            delegate = providedDelegate
        }
        func getPOSTData(){
            API.request(URL, method: .post).responseJSON
            { response in
                if response.result.value != nil {
                    //print("JSON: \(JSON)")
                    self.delegate?.onSuccess(jsonData: JSON as! [String : Any])
                } else {
                    self.delegate?.onFailure(error: "No JSON Data")
                }
            }
        }
    }
    

    查看控制器文件

    protocol APIDelegate{
        func onSuccess(jsonData: [String:Any])
        func onFailure(error: Any)
    }
    UIViewControllerName : UIViewController, APIDelegate{
        var delegate: APIDelegate?
    
        func testAPICall(sender: UIButton){
            let client = API(providedDelegate: delegate!)
            client.getPOSTData()
        }
    
        func onSuccess(jsonData: [String:Any]) {
            print("JSON: \(jsonData)")
        }
        func onFailure(error: Any) {
            print(error)
        }
    
    }
    

    问题

    从长远来看,这会导致问题吗?有没有更好的方法在另一个类的异步任务之间共享数据备份到调用UIViewController?

2 个答案:

答案 0 :(得分:2)

基本上你的代码应该有效,但我强烈建议使用回调闭包而不是协议/委托。

代码使用枚举来返回单个值和switch语句来处理调用方的案例:

enum APIResult {
    case success([String:Any])
    case failure(Any)
}

class UIViewControllerName : UIViewController {

    func testAPICall(sender: UIButton) {

        let client = API()
        client.getPOSTData() { result in
            switch result {
               case .success(let jsonData) :  print("JSON: \(jsonData)")
               case .failure(let error) :  print("JSON: \(error)")
            }
        }
    }
}


class API {

    func getPOSTData(completion: (APIResult)->() ) {
        API.request(URL, method: .post).responseJSON
            { response in
                if response.result.value != nil {
                    //print("JSON: \(JSON)")
                    completion(.success(JSON as! [String : Any]))
                } else {
                    completion(.failure("No JSON Data"))
                }
        }
    }
}

答案 1 :(得分:1)

您可以通过结束传递数据

声明阻止

typealias responseHandler = (_ responseObject: [String : Any]) -> Void

 func getPOSTData(with callback : responseHandler){
        API.request(URL, method: .post).responseJSON
            { response in
                if response.result.value != nil {
                    //print("JSON: \(JSON)")
                    self.delegate?.onSuccess(jsonData: JSON as! [String : Any])
                    callback(JSON as! [String : Any])

                } else {
                    callback([:] as! [String : Any] )
                }
        }
    }

如下调用

client.getPOSTData { (responseData) in
            print(responseData)
            // here your data
        }