-
Notifications
You must be signed in to change notification settings - Fork 0
/
Router.swift
97 lines (81 loc) · 3.64 KB
/
Router.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//
// NetworkService.swift
// NetworkLayer
//
// Created by Malcolm Kumwenda on 2018/03/07.
// Copyright © 2018 Malcolm Kumwenda. All rights reserved.
//
import Foundation
typealias NetworkRouterCompletion = (_ data: Data?,_ response: URLResponse?,_ error: Error?)->()
protocol NetworkRouter: class {
associatedtype EndPoint: EndPointType
func request(_ route: EndPoint, completion: @escaping NetworkRouterCompletion)
func cancel()
}
class Router<EndPoint: EndPointType>: NetworkRouter {
private var task: URLSessionTask?
func request(_ route: EndPoint, completion: @escaping NetworkRouterCompletion) {
let session = URLSession.shared
do {
let request = try self.buildRequest(from: route)
NetworkLogger.log(request: request)
task = session.dataTask(with: request, completionHandler: { data, response, error in
completion(data, response, error)
})
}catch {
completion(nil, nil, error)
}
self.task?.resume()
}
func cancel() {
self.task?.cancel()
}
fileprivate func buildRequest(from route: EndPoint) throws -> URLRequest {
var request = URLRequest(url: route.baseURL.appendingPathComponent(route.path),
cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 10.0)
request.httpMethod = route.httpMethod.rawValue
do {
switch route.task {
case .request:
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
case .requestParameters(let bodyParameters,
let bodyEncoding,
let urlParameters):
try self.configureParameters(bodyParameters: bodyParameters,
bodyEncoding: bodyEncoding,
urlParameters: urlParameters,
request: &request)
case .requestParametersAndHeaders(let bodyParameters,
let bodyEncoding,
let urlParameters,
let additionalHeaders):
self.addAdditionalHeaders(additionalHeaders, request: &request)
try self.configureParameters(bodyParameters: bodyParameters,
bodyEncoding: bodyEncoding,
urlParameters: urlParameters,
request: &request)
}
return request
} catch {
throw error
}
}
fileprivate func configureParameters(bodyParameters: Parameters?,
bodyEncoding: ParameterEncoding,
urlParameters: Parameters?,
request: inout URLRequest) throws {
do {
try bodyEncoding.encode(urlRequest: &request,
bodyParameters: bodyParameters, urlParameters: urlParameters)
} catch {
throw error
}
}
fileprivate func addAdditionalHeaders(_ additionalHeaders: HTTPHeaders?, request: inout URLRequest) {
guard let headers = additionalHeaders else { return }
for (key, value) in headers {
request.setValue(value, forHTTPHeaderField: key)
}
}
}