ios - 来自 ViewController 外部的 Alamofire 请求

标签 ios swift rest alamofire

有什么方法可以从 ViewController (UITableViewController) 外部通过 alamofire 调用请求,然后用响应中的数据填充 tablewView?现在我在 Controller 中创建了一个函数,在获取数据后调用 tablewView 的 reloadData()。但是有没有办法创建这样的方法:

class InsuranceServices {

    class func getContracts(table : UITableView) -> [Contract] {
        var contracts = [Contract]()
        let headers : HTTPHeaders = [
            "Content-Type":"application/json"
        ]
        let params : Parameters = [String:Any]()

        Alamofire.request("http://test:9090/testService/getContracts", method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).validate().responseJSON(completionHandler: {response -> Void in

            switch response.result {
            case .success(let value):
                let json = JSON(value)
                for data in json["data"].arrayValue {
                    let contract = Contract(json: data)
                    print(contract.fullName!)
                    contracts.append(contract)
                }
            case .failure(let error):
                print(error)
            }
            table.reloadData()
        })
        return contracts
    }

}

这个方法对我不起作用。也许还有另一种方法?我认为在 Controller 内部创建服务方法是不正确的。

最佳答案

您的 ViewControllerAlamofire 应该有明显的区别。 一种实现方法类似于您编写的方法,但您的函数不应采用 UITableView 本身,而应采用接收 [Contract] 的完成 block 。

它看起来像这样:

class func getContracts(completion: @escaping ([Contract])→Void) { 
    //...
    Alamofire.request(...).responseJSON(completionHandler: {response -> Void in

        switch response.result {

        case .success(let value):
            let json = JSON(value)
            var contracts = [Contract]()
            for data in json["data"].arrayValue {
                let contract = Contract(json: data)
                contracts.append(contract)                    
            }
            completion(contracts)

        case .failure(let error):
            print(error)
            completion([])
        }
    })
}

另一件事是你不能在函数的返回值中返回请求的结果(在你的例子中是 Contract 的数组)。由于 Alamofire 异步调用请求,它会比函数返回晚得多结束。这就是为什么如您所见,我编写的函数签名不返回任何内容。相反,它会在请求准备好且数据可用时调用 completion 闭包。

请注意,即使在失败时,您也必须调用completion 闭包!否则调用者(在您的情况下是您的 View Controller )将永远等待请求而不知道它失败了....

然后您可以像这样调用该函数,确保您不会因 self 导致内存泄漏:

InsuranceServices.getContracts(completionHandler: { [weak self] data in 
    self?.contracts = data
    self?.tableView.reloadData() 
})

关于ios - 来自 ViewController 外部的 Alamofire 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41351484/

相关文章:

ios - 从一种模态 VC 到另一种模态 VC 的快速过渡

ios - 如何将一个数组添加到另一个数组

ios - 在 NSRegularExpression 模式中使用捕获组

iphone - iPad 应用程序插件

ios - 从托管内容重新下载一次应用内购买

java - Retrofit2 - 列表最终为空,即使在填充之后也是如此。

c# - 访问rest web服务时,如何在android中使用HttpPost和NameValuePair传递参数值?

ios - UIPopoverController 内的导航

ios - 快速日期格式化,从服务器返回的日期与发送到服务器的日期不同

php - 从 php 脚本调用中获取响应