let route:EndPointsManager.Route<Int,String> = .init(endpoint: <#endpoint#>, info: <#info#>)
let urlManager = EndPointsManager(scheme: <#scheme#>, host: <#host#>, port: <#port#>)
urlManager.fetch(from: route, onConfig: { (url) -> URLRequest in
return URLRequest(url: url!)
}) { (result) in
switch result{
case .success( let model):
///get model
case .apiError(let fail):
///get json error
case .failure(let error):
///get other error
}
}
Last active
June 11, 2019 12:10
-
-
Save ytyubox/2154e8502ed30b1cd1424961778b7d6a to your computer and use it in GitHub Desktop.
A API Endpoint with two response
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EndPointsManager{ | |
struct Route<Model:Codable,APIError:Codable>{ | |
let endpoint:String | |
let info:[String:String] | |
} | |
private let urlComponents:URLComponents | |
let session = URLSession.shared | |
init(scheme:String, host:String, port:Int){ | |
var urlComponents = URLComponents() | |
urlComponents.scheme = scheme | |
urlComponents.host = host | |
urlComponents.port = port | |
self.urlComponents = urlComponents | |
} | |
enum URLResult<Model:Codable,APIError:Codable,Err:Error>{ | |
case success(Model) | |
case apiError(APIError) | |
case failure(Err) | |
} | |
func fetch<Model: Codable, Fail:Codable> ( | |
from route: Route<Model,Fail>, | |
onConfig: @escaping (URL?) -> URLRequest, | |
then: @escaping (URLResult<Model,Fail,Error>) -> Void) { | |
var url = urlComponents | |
url.path = route.endpoint | |
let request = onConfig(url.url) | |
let task = session.dataTask(with: request) { (data, reponse, error) in | |
var result:URLResult<Model,Fail,Error> | |
defer { | |
DispatchQueue.main.async { then(result)} | |
} | |
if let error = error { | |
result = .failure(error) | |
return | |
} | |
guard let _ = reponse as? HTTPURLResponse else { | |
result = .failure(URLError.reponseUnknow) | |
return | |
} | |
guard let data = data else { | |
result = .failure(URLError.noData) | |
return | |
} | |
if let model = try? JSONDecoder().decode(Model.self, from: data) { | |
result = .success(model) | |
} else { | |
do { | |
let apiFail = try JSONDecoder().decode(Fail.self, from: data) | |
result = .apiError(apiFail) | |
}catch { | |
result = .failure(error) | |
} | |
} | |
} | |
DispatchQueue.global().async { | |
task.resume() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@slamdon 這個函式可以將 2 個可能的結構解析, 有想過要使用
onComplete: (Result)->Void
解耦, 可以試試修改看看