-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathIterableRequestUtil.swift
More file actions
122 lines (98 loc) · 4.64 KB
/
IterableRequestUtil.swift
File metadata and controls
122 lines (98 loc) · 4.64 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// Copyright © 2018 Iterable. All rights reserved.
//
/// This is a utility class which takes an apiEndpoint, path, header, args etc to create URLRequest objects.
/// The methods should be generic and not specific to Iterable.
import Foundation
struct IterableRequestUtil {
static func createGetRequest(forApiEndPoint apiEndPoint: String,
path: String,
headers: [String: String]? = nil,
args: [String: String]? = nil) -> URLRequest? {
guard let url = getUrlComponents(forApiEndPoint: apiEndPoint, path: path, args: args)?.url else {
ITBError("Failed to create GET request URL")
return nil
}
var request = URLRequest(url: url)
addHeaders(headers: headers, toRequest: &request)
request.httpMethod = Const.Http.GET
return request
}
static func createPostRequest(forApiEndPoint apiEndPoint: String,
path: String,
headers: [String: String]? = nil,
args: [String: String]? = nil,
body: [AnyHashable: Any]? = nil) -> URLRequest? {
createPostRequest(forApiEndPoint: apiEndPoint,
path: path,
headers: headers,
args: args,
body: dictToJsonData(body))
}
static func createPostRequest<T: Encodable>(forApiEndPoint apiEndPoint: String,
path: String,
headers: [String: String]? = nil,
args: [String: String]? = nil,
body: T) -> URLRequest? {
createPostRequest(forApiEndPoint: apiEndPoint,
path: path,
headers: headers,
args: args,
body: try? JSONEncoder().encode(body))
}
static func createPostRequest(forApiEndPoint apiEndPoint: String,
path: String,
headers: [String: String]? = nil,
args: [String: String]? = nil,
body: Data? = nil) -> URLRequest? {
guard let url = getUrlComponents(forApiEndPoint: apiEndPoint, path: path, args: args)?.url else {
ITBError("Failed to create POST request URL")
return nil
}
var request = URLRequest(url: url)
addHeaders(headers: headers, toRequest: &request)
request.httpMethod = Const.Http.POST
request.httpBody = body
return request
}
static func dictToJsonData(_ dict: [AnyHashable: Any]?) -> Data? {
guard let dict = dict else {
return nil
}
return try? JSONSerialization.data(withJSONObject: dict, options: [])
}
static func pathCombine(paths: [String]) -> String {
paths.reduce("", pathCombine)
}
private static func addHeaders(headers: [String: String]?, toRequest request: inout URLRequest) {
if let headers = headers {
headers.forEach {
request.setValue($0.value, forHTTPHeaderField: $0.key)
}
}
}
private static func getUrlComponents(forApiEndPoint apiEndPoint: String, path: String, args: [String: String]? = nil) -> URLComponents? {
let endPointCombined = pathCombine(path1: apiEndPoint, path2: path)
guard var components = URLComponents(string: "\(endPointCombined)") else {
ITBError("Failed to create URLComponents - apiEndPoint: '\(apiEndPoint)', path: '\(path)', combined: '\(endPointCombined)'")
return nil
}
if let args = args {
components.queryItems = args.map { URLQueryItem(name: $0.key, value: $0.value) }
}
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
return components
}
private static func pathCombine(path1: String, path2: String) -> String {
var result = path1
if result.hasSuffix("/") {
result.removeLast()
}
// result has no ending slashes, add one if needed
if !result.isEmpty, !path2.isEmpty, !path2.hasPrefix("/") {
result.append("/")
}
result.append(path2)
return result
}
}