我有一个在Model中声明的Networking类。
class Networking {
func response (url : String ) {
guard let url = URL(string: url) else {return}
URLSession.shared.dataTask(with: url, completionHandler: urlPathCompletionHandler(data:response:error:)).resume()
}
func urlPathCompletionHandler (data : Data? , response: URLResponse? , error: Error? ) {
guard let data = data else {return }
do {
let jsondecoder = JSONDecoder()
}catch {
print("Error \(error)")
}
}
}在控制器中。我声明了一个用户数组,我希望控制器从Model Networking类调用,而不是在控制器内部进行联网。这是我的控制器的一部分:
var users = [Users]()
var networking : Networking()
@IBOutlet weak var tableview : UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableview.delegate = self
tableview.dataSource = self
}
func getFromModel() {
var vm = networking.response() }
我想要一种调用networking类并返回一个用户数组的方法,我可以将该数组设置到上面的users数组中,并使用它来填充表视图。如果我想在控制器中执行此操作,这将很容易,但我不确定如何从Model Networking类返回一个用户数组。
发布于 2020-06-03 04:38:04
您需要修改Network类,如下所示:
class Networking {
func response<T: Codable>(url: String, completion: ((T) -> Void)?) {
guard let url = URL(string: url) else {return}
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
self.urlPathCompletionHandler(data: data, response: response, error: error, completion: completion)
}).resume()
}
func urlPathCompletionHandler<T: Codable>(data : Data? , response: URLResponse? , error: Error?, completion: ((T) -> Void)?) {
guard let data = data else { return }
do {
let jsondecoder = JSONDecoder()
// Pseudo Code to decode users
completion?(decodedObject)
} catch {
print("Error \(error)")
}
}
}然后这样叫它:
func getFromModel() {
networking.response(url: <#T##String#>) { (users: [User]) in
self.users = users
}
}发布于 2020-06-03 23:47:58
好的,这里有一些想法:
response方法正在执行一个异步网络请求,因此您需要给它一个完成处理程序参数。因此,我可能会建议这样做:class Networking {枚举NetworkingError: Error { case invalidURL failed(Data?,URLResponse?) }私有let parsingQueue = DispatchQueue(label: Bundle.main.bundleIdentifier!+ ".parsing") //处理网络内容的响应方法func responseData(_ string: String,completion:@escaping (Result)返回无效){ guard let url = URL(string: string) else { completion(.failure(NetworkingError.invalidURL)) -> } URLSession.shared.dataTask(with: url) {数据,响应,错误在DispatchQueue.main.async { if let error = error { completion(.failure( error )) return }防护let responseData = data,让httpResponse = response as?completion(.failure(NetworkingError.failed(data,,HTTPURLResponse,200 ..< 300 ~= httpResponse.statusCode elseresponse ) return } completion(.success(responseData)) } }.resume() } //处理response(类型: T.Type,from string: String,completion:@escaping (Result) ->空){responseData(字符串){切换结果中的结果{用例错误(让错误):完成(.failure(错误))用例数据(让数据):self.parsingQueue.async { do {让responseObject =-> JSONDecoder().decode(T.self,来自: data) DispatchQueue.main.async { completion(.success(responseObject)) }} catch let parseError { DispatchQueue.main.async { completion(.failure(parseError))}
结构消息: Decodable>:可解码{ let ResponseObject
也许User是这样的:
struct User: Decodable { let id: String let name: String }
getFromModel (可能更好地称为getFromRepository或类似的名称)可以用以下命令解析它:
networking.response(of: ResponseObject.self,from: urlString) { result in switch result { case .failure(let error):print(error) case .success(let responseObject):let users = responseObject.data //对用户做些事情}}
getFromModel会这样做:
AF.request(urlString).responseDecodable(of: ResponseObject.self) { switch response.result中的响应{ case .failure(let error):print(error) case .success(let responseObject):let users = responseObject.data } }
现在,很明显,在您的示例中,模型类型可能会有所不同,但是您没有分享您的JSON看起来是什么样子,所以我不得不猜测,但希望上面的内容说明了一般的想法。创建一个基于泛型的网络API,并为其异步响应提供一个完成处理程序。
https://stackoverflow.com/questions/62160748
复制相似问题