MVC网络Swift
我在模型中声明了这个网络类MVC网络Swift,swift,Swift,我在模型中声明了这个网络类 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()
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)")
}
}
}
在控制器中。我有一个我声明的用户数组,我希望控制器从ModelNetworking类调用,而不是在控制器内部进行联网。这是我的控制器的一部分:
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类返回一组用户。您需要修改网络类,如下所示:
班级网络{
func响应(url:字符串,完成:((T)->Void)?){
guard let url=url(字符串:url)else{return}
URLSession.shared.dataTask(在中带有:url,completionHandler:{(数据,响应,错误))
urlPathCompletionHandler(数据:数据,响应:响应,错误:错误,完成:完成)
})1.简历()
}
func urlPathCompletionHandler(数据:数据?,响应:URLResponse?,错误:错误?,完成:((T)->Void)?){
guard let data=data else{return}
做{
让jsondecoder=jsondecoder()
//用于解码用户的伪代码
完成?(解码对象)
}抓住{
打印(“错误\(错误)”)
}
}
}
这样称呼它:
func getFromModel(){
networking.response(url:){(用户:[用户])在
self.users=用户
}
}
您需要像这样修改网络类:
班级网络{
func响应(url:字符串,完成:((T)->Void)?){
guard let url=url(字符串:url)else{return}
URLSession.shared.dataTask(在中带有:url,completionHandler:{(数据,响应,错误))
urlPathCompletionHandler(数据:数据,响应:响应,错误:错误,完成:完成)
})1.简历()
}
func urlPathCompletionHandler(数据:数据?,响应:URLResponse?,错误:错误?,完成:((T)->Void)?){
guard let data=data else{return}
做{
让jsondecoder=jsondecoder()
//用于解码用户的伪代码
完成?(解码对象)
}抓住{
打印(“错误\(错误)”)
}
}
}
这样称呼它:
func getFromModel(){
networking.response(url:){(用户:[用户])在
self.users=用户
}
}
好的,有一些想法:
response
方法正在执行异步网络请求,因此需要为其提供一个完成处理程序参数。因此,我可以建议如下:
class Networking {
enum NetworkingError: Error {
case invalidURL
case failed(Data?, URLResponse?)
}
private let parsingQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".parsing")
// response method to handle network stuff
func responseData(_ string: String, completion: @escaping (Result<Data, Error>) -> Void) {
guard let url = URL(string: string) else {
completion(.failure(NetworkingError.invalidURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
if let error = error {
completion(.failure(error))
return
}
guard
let responseData = data,
let httpResponse = response as? HTTPURLResponse,
200 ..< 300 ~= httpResponse.statusCode
else {
completion(.failure(NetworkingError.failed(data, response)))
return
}
completion(.success(responseData))
}
}.resume()
}
// response method to handle the JSON parsing
func response<T: Decodable>(of type: T.Type, from string: String, completion: @escaping (Result<T, Error>) -> Void) {
responseData(string) { result in
switch result {
case .failure(let error):
completion(.failure(error))
case .success(let data):
self.parsingQueue.async {
do {
let responseObject = try JSONDecoder().decode(T.self, from: data)
DispatchQueue.main.async {
completion(.success(responseObject))
}
} catch let parseError {
DispatchQueue.main.async {
completion(.failure(parseError))
}
}
}
}
}
}
}
getFromModel
(最好称为getFromRepository
或类似的东西)可以用以下方法解析它:
networking.response(of: ResponseObject<[User]>.self, from: urlString) { result in
switch result {
case .failure(let error):
print(error)
case .success(let responseObject):
let users = responseObject.data
// do something with users
}
}
现在,很明显,在您的示例中,模型类型可能会有所不同,但是您没有分享JSON的外观,因此我不得不猜测,但希望上面的内容能够说明一般的想法。制作一个基于泛型的网络API,并为其异步响应提供一个完成处理程序。好的,有一些想法:
response
方法正在执行异步网络请求,因此需要为其提供一个完成处理程序参数。因此,我可以建议如下:
class Networking {
enum NetworkingError: Error {
case invalidURL
case failed(Data?, URLResponse?)
}
private let parsingQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".parsing")
// response method to handle network stuff
func responseData(_ string: String, completion: @escaping (Result<Data, Error>) -> Void) {
guard let url = URL(string: string) else {
completion(.failure(NetworkingError.invalidURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
if let error = error {
completion(.failure(error))
return
}
guard
let responseData = data,
let httpResponse = response as? HTTPURLResponse,
200 ..< 300 ~= httpResponse.statusCode
else {
completion(.failure(NetworkingError.failed(data, response)))
return
}
completion(.success(responseData))
}
}.resume()
}
// response method to handle the JSON parsing
func response<T: Decodable>(of type: T.Type, from string: String, completion: @escaping (Result<T, Error>) -> Void) {
responseData(string) { result in
switch result {
case .failure(let error):
completion(.failure(error))
case .success(let data):
self.parsingQueue.async {
do {
let responseObject = try JSONDecoder().decode(T.self, from: data)
DispatchQueue.main.async {
completion(.success(responseObject))
}
} catch let parseError {
DispatchQueue.main.async {
completion(.failure(parseError))
}
}
}
}
}
}
}
getFromModel
(最好称为getFromRepository
或类似的东西)可以用以下方法解析它:
networking.response(of: ResponseObject<[User]>.self, from: urlString) { result in
switch result {
case .failure(let error):
print(error)
case .success(let responseObject):
let users = responseObject.data
// do something with users
}
}
现在,很明显,在您的示例中,模型类型可能会有所不同,但是您没有分享JSON的外观,因此我不得不猜测,但希望上面的内容能够说明一般的想法。创建一个基于泛型的网络API,并为其异步响应提供一个完成处理程序。但现在Networking类只支持下载和解码用户对象。使用泛型更新。但现在Networking类只支持下载和解码用户对象。使用泛型更新。
AF.request(urlString).responseDecodable(of: ResponseObject<[User]>.self) { response in
switch response.result {
case .failure(let error):
print(error)
case .success(let responseObject):
let users = responseObject.data
}
}