Skip to content

Instantly share code, notes, and snippets.

@ytyubox
Last active June 11, 2019 12:10
Show Gist options
  • Save ytyubox/2154e8502ed30b1cd1424961778b7d6a to your computer and use it in GitHub Desktop.
Save ytyubox/2154e8502ed30b1cd1424961778b7d6a to your computer and use it in GitHub Desktop.
A API Endpoint with two response

usage

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
       }
}
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()
}
}
}
@slamdon
Copy link

slamdon commented Jun 8, 2019

我剛才的狀況是無法確定 data 的結構

@ytyubox
Copy link
Author

ytyubox commented Jun 8, 2019

我剛才的狀況是無法確定 data 的結構

@slamdon 這個函式可以將 2 個可能的結構解析, 有想過要使用 onComplete: (Result)->Void 解耦, 可以試試修改看看

@ytyubox
Copy link
Author

ytyubox commented Jun 11, 2019

@slamdon 我更新了, 看看吧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment