首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC Networking Swift

MVC Networking Swift
EN

Stack Overflow用户
提问于 2020-06-03 04:20:51
回答 2查看 135关注 0票数 0

我有一个在Model中声明的Networking类。

代码语言:javascript
复制
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类调用,而不是在控制器内部进行联网。这是我的控制器的一部分:

代码语言:javascript
复制
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类返回一个用户数组。

EN

回答 2

Stack Overflow用户

发布于 2020-06-03 04:38:04

您需要修改Network类,如下所示:

代码语言:javascript
复制
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)")
        }
    }
}

然后这样叫它:

代码语言:javascript
复制
func getFromModel() {
    networking.response(url: <#T##String#>) { (users: [User]) in
        self.users = users
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-06-03 23:47:58

好的,这里有一些想法:

  1. 您的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))}

  • 这显然假设你有一些可编码的类型。例如,API在其响应中通常具有一些公共结构:

结构消息: 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 //对用户做些事情}}

  • 值得一试,如果你不想写自己的网络代码,你可以使用Alamofire,然后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,并为其异步响应提供一个完成处理程序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62160748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档