Skip to content

Commit 82f49fa

Browse files
authored
Merge pull request #49 from freshOS/dateDecodingStrategy
Makes JSONDecoder configurable
2 parents 9980135 + 4ffbaff commit 82f49fa

4 files changed

+88
-101
lines changed

Sources/Networking/Calls/NetworkingClient+Decodable.swift

+20-20
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public extension NetworkingClient {
1414
params: Params = Params(),
1515
keypath: String? = nil) -> AnyPublisher<T, Error> {
1616
return get(route, params: params)
17-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
17+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
1818
.receive(on: DispatchQueue.main)
1919
.eraseToAnyPublisher()
2020
}
@@ -25,7 +25,7 @@ public extension NetworkingClient {
2525
keypath: String? = nil) -> AnyPublisher<T, Error> where T: Collection {
2626
let keypath = keypath ?? defaultCollectionParsingKeyPath
2727
return get(route, params: params)
28-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
28+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
2929
.receive(on: DispatchQueue.main)
3030
.eraseToAnyPublisher()
3131
}
@@ -34,7 +34,7 @@ public extension NetworkingClient {
3434
params: Params = Params(),
3535
keypath: String? = nil) -> AnyPublisher<T, Error> {
3636
return post(route, params: params)
37-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
37+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
3838
.receive(on: DispatchQueue.main)
3939
.eraseToAnyPublisher()
4040
}
@@ -45,7 +45,7 @@ public extension NetworkingClient {
4545
keypath: String? = nil) -> AnyPublisher<T, Error> where T: Collection {
4646
let keypath = keypath ?? defaultCollectionParsingKeyPath
4747
return post(route, params: params)
48-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
48+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
4949
.receive(on: DispatchQueue.main)
5050
.eraseToAnyPublisher()
5151
}
@@ -54,7 +54,7 @@ public extension NetworkingClient {
5454
params: Params = Params(),
5555
keypath: String? = nil) -> AnyPublisher<T, Error> {
5656
return put(route, params: params)
57-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
57+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
5858
.receive(on: DispatchQueue.main)
5959
.eraseToAnyPublisher()
6060
}
@@ -65,7 +65,7 @@ public extension NetworkingClient {
6565
keypath: String? = nil) -> AnyPublisher<T, Error> where T: Collection {
6666
let keypath = keypath ?? defaultCollectionParsingKeyPath
6767
return put(route, params: params)
68-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
68+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
6969
.receive(on: DispatchQueue.main)
7070
.eraseToAnyPublisher()
7171
}
@@ -74,7 +74,7 @@ public extension NetworkingClient {
7474
params: Params = Params(),
7575
keypath: String? = nil) -> AnyPublisher<T, Error> {
7676
return patch(route, params: params)
77-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
77+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
7878
.receive(on: DispatchQueue.main)
7979
.eraseToAnyPublisher()
8080
}
@@ -85,7 +85,7 @@ public extension NetworkingClient {
8585
keypath: String? = nil) -> AnyPublisher<T, Error> where T: Collection {
8686
let keypath = keypath ?? defaultCollectionParsingKeyPath
8787
return patch(route, params: params)
88-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
88+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
8989
.receive(on: DispatchQueue.main)
9090
.eraseToAnyPublisher()
9191
}
@@ -94,7 +94,7 @@ public extension NetworkingClient {
9494
params: Params = Params(),
9595
keypath: String? = nil) -> AnyPublisher<T, Error> {
9696
return delete(route, params: params)
97-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
97+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
9898
.receive(on: DispatchQueue.main)
9999
.eraseToAnyPublisher()
100100
}
@@ -105,7 +105,7 @@ public extension NetworkingClient {
105105
keypath: String? = nil) -> AnyPublisher<T, Error> where T: Collection {
106106
let keypath = keypath ?? defaultCollectionParsingKeyPath
107107
return delete(route, params: params)
108-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
108+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
109109
.receive(on: DispatchQueue.main)
110110
.eraseToAnyPublisher()
111111
}
@@ -118,7 +118,7 @@ public extension NetworkingClient {
118118
params: Params = Params(),
119119
keypath: String? = nil) async throws -> T {
120120
let json: Any = try await get(route, params: params)
121-
let model:T = try NetworkingParser().toModel(json, keypath: keypath)
121+
let model:T = try self.toModel(json, keypath: keypath)
122122
return model
123123
}
124124

@@ -127,66 +127,66 @@ public extension NetworkingClient {
127127
keypath: String? = nil) async throws -> T where T: Collection {
128128
let keypath = keypath ?? defaultCollectionParsingKeyPath
129129
let json: Any = try await get(route, params: params)
130-
return try NetworkingParser().toModel(json, keypath: keypath)
130+
return try self.toModel(json, keypath: keypath)
131131
}
132132

133133
func post<T: Decodable>(_ route: String,
134134
params: Params = Params(),
135135
keypath: String? = nil) async throws -> T {
136136
let json: Any = try await post(route, params: params)
137-
return try NetworkingParser().toModel(json, keypath: keypath)
137+
return try self.toModel(json, keypath: keypath)
138138
}
139139

140140
func post<T: Decodable>(_ route: String,
141141
params: Params = Params(),
142142
keypath: String? = nil) async throws -> T where T: Collection {
143143
let keypath = keypath ?? defaultCollectionParsingKeyPath
144144
let json: Any = try await post(route, params: params)
145-
return try NetworkingParser().toModel(json, keypath: keypath)
145+
return try self.toModel(json, keypath: keypath)
146146
}
147147

148148
func put<T: Decodable>(_ route: String,
149149
params: Params = Params(),
150150
keypath: String? = nil) async throws -> T {
151151
let json: Any = try await put(route, params: params)
152-
return try NetworkingParser().toModel(json, keypath: keypath)
152+
return try self.toModel(json, keypath: keypath)
153153
}
154154

155155
func put<T: Decodable>(_ route: String,
156156
params: Params = Params(),
157157
keypath: String? = nil) async throws -> T where T: Collection {
158158
let keypath = keypath ?? defaultCollectionParsingKeyPath
159159
let json: Any = try await put(route, params: params)
160-
return try NetworkingParser().toModel(json, keypath: keypath)
160+
return try self.toModel(json, keypath: keypath)
161161
}
162162

163163
func patch<T: Decodable>(_ route: String,
164164
params: Params = Params(),
165165
keypath: String? = nil) async throws -> T {
166166
let json: Any = try await patch(route, params: params)
167-
return try NetworkingParser().toModel(json, keypath: keypath)
167+
return try self.toModel(json, keypath: keypath)
168168
}
169169

170170
func patch<T: Decodable>(_ route: String,
171171
params: Params = Params(),
172172
keypath: String? = nil) async throws -> T where T: Collection {
173173
let keypath = keypath ?? defaultCollectionParsingKeyPath
174174
let json: Any = try await patch(route, params: params)
175-
return try NetworkingParser().toModel(json, keypath: keypath)
175+
return try self.toModel(json, keypath: keypath)
176176
}
177177

178178
func delete<T: Decodable>(_ route: String,
179179
params: Params = Params(),
180180
keypath: String? = nil) async throws -> T {
181181
let json: Any = try await delete(route, params: params)
182-
return try NetworkingParser().toModel(json, keypath: keypath)
182+
return try self.toModel(json, keypath: keypath)
183183
}
184184

185185
func delete<T: Decodable>(_ route: String,
186186
params: Params = Params(),
187187
keypath: String? = nil) async throws -> T where T: Collection {
188188
let keypath = keypath ?? defaultCollectionParsingKeyPath
189189
let json: Any = try await delete(route, params: params)
190-
return try NetworkingParser().toModel(json, keypath: keypath)
190+
return try self.toModel(json, keypath: keypath)
191191
}
192192
}

Sources/Networking/Calls/NetworkingClient+NetworkingJSONDecodable.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public extension NetworkingClient {
2020
params: Params = Params(),
2121
keypath: String? = nil) -> AnyPublisher<T, Error> {
2222
return get(route, params: params)
23-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
23+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
2424
.receive(on: DispatchQueue.main)
2525
.eraseToAnyPublisher()
2626
}
@@ -31,7 +31,7 @@ public extension NetworkingClient {
3131
keypath: String? = nil) -> AnyPublisher<[T], Error> {
3232
let keypath = keypath ?? defaultCollectionParsingKeyPath
3333
return get(route, params: params)
34-
.tryMap { json -> [T] in try NetworkingParser().toModels(json, keypath: keypath) }
34+
.tryMap { json -> [T] in try self.toModels(json, keypath: keypath) }
3535
.receive(on: DispatchQueue.main)
3636
.eraseToAnyPublisher()
3737
}
@@ -40,7 +40,7 @@ public extension NetworkingClient {
4040
params: Params = Params(),
4141
keypath: String? = nil) -> AnyPublisher<T, Error> {
4242
return post(route, params: params)
43-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
43+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
4444
.receive(on: DispatchQueue.main)
4545
.eraseToAnyPublisher()
4646
}
@@ -51,7 +51,7 @@ public extension NetworkingClient {
5151
keypath: String? = nil) -> AnyPublisher<[T], Error> {
5252
let keypath = keypath ?? defaultCollectionParsingKeyPath
5353
return post(route, params: params)
54-
.tryMap { json -> [T] in try NetworkingParser().toModels(json, keypath: keypath) }
54+
.tryMap { json -> [T] in try self.toModels(json, keypath: keypath) }
5555
.receive(on: DispatchQueue.main)
5656
.eraseToAnyPublisher()
5757
}
@@ -60,7 +60,7 @@ public extension NetworkingClient {
6060
params: Params = Params(),
6161
keypath: String? = nil) -> AnyPublisher<T, Error> {
6262
return put(route, params: params)
63-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
63+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
6464
.receive(on: DispatchQueue.main)
6565
.eraseToAnyPublisher()
6666
}
@@ -72,7 +72,7 @@ public extension NetworkingClient {
7272
keypath: String? = nil) -> AnyPublisher<[T], Error> {
7373
let keypath = keypath ?? defaultCollectionParsingKeyPath
7474
return put(route, params: params)
75-
.tryMap { json -> [T] in try NetworkingParser().toModels(json, keypath: keypath) }
75+
.tryMap { json -> [T] in try self.toModels(json, keypath: keypath) }
7676
.receive(on: DispatchQueue.main)
7777
.eraseToAnyPublisher()
7878
}
@@ -81,7 +81,7 @@ public extension NetworkingClient {
8181
params: Params = Params(),
8282
keypath: String? = nil) -> AnyPublisher<T, Error> {
8383
return patch(route, params: params)
84-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
84+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
8585
.receive(on: DispatchQueue.main)
8686
.eraseToAnyPublisher()
8787
}
@@ -92,7 +92,7 @@ public extension NetworkingClient {
9292
keypath: String? = nil) -> AnyPublisher<[T], Error> {
9393
let keypath = keypath ?? defaultCollectionParsingKeyPath
9494
return patch(route, params: params)
95-
.tryMap { json -> [T] in try NetworkingParser().toModels(json, keypath: keypath) }
95+
.tryMap { json -> [T] in try self.toModels(json, keypath: keypath) }
9696
.receive(on: DispatchQueue.main)
9797
.eraseToAnyPublisher()
9898
}
@@ -101,7 +101,7 @@ public extension NetworkingClient {
101101
params: Params = Params(),
102102
keypath: String? = nil) -> AnyPublisher<T, Error> {
103103
return delete(route, params: params)
104-
.tryMap { json -> T in try NetworkingParser().toModel(json, keypath: keypath) }
104+
.tryMap { json -> T in try self.toModel(json, keypath: keypath) }
105105
.receive(on: DispatchQueue.main)
106106
.eraseToAnyPublisher()
107107
}
@@ -112,7 +112,7 @@ public extension NetworkingClient {
112112
keypath: String? = nil) -> AnyPublisher<[T], Error> {
113113
let keypath = keypath ?? defaultCollectionParsingKeyPath
114114
return delete(route, params: params)
115-
.tryMap { json -> [T] in try NetworkingParser().toModels(json, keypath: keypath) }
115+
.tryMap { json -> [T] in try self.toModels(json, keypath: keypath) }
116116
.receive(on: DispatchQueue.main)
117117
.eraseToAnyPublisher()
118118
}

Sources/Networking/NetworkingClient.swift

+58
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class NetworkingClient {
1515
public var timeout: TimeInterval?
1616
public var sessionConfiguration = URLSessionConfiguration.default
1717
public var requestRetrier: NetworkRequestRetrier?
18+
public var jsonDecoderFactory: (() -> JSONDecoder)?
1819

1920
/**
2021
Prints network calls to the console.
@@ -32,5 +33,62 @@ public class NetworkingClient {
3233
self.baseURL = baseURL
3334
self.timeout = timeout
3435
}
36+
37+
public func toModel<T: NetworkingJSONDecodable>(_ json: Any, keypath: String? = nil) throws -> T {
38+
do {
39+
let data = resourceData(from: json, keypath: keypath)
40+
return try T.decode(data)
41+
} catch (let error) {
42+
throw error
43+
}
44+
}
45+
46+
public func toModel<T: Decodable>(_ json: Any, keypath: String? = nil) throws -> T {
47+
do {
48+
let jsonObject = resourceData(from: json, keypath: keypath)
49+
let decoder = jsonDecoderFactory?() ?? JSONDecoder()
50+
let data = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
51+
let model = try decoder.decode(T.self, from: data)
52+
return model
53+
} catch (let error) {
54+
throw error
55+
}
56+
}
57+
58+
public func toModels<T: NetworkingJSONDecodable>(_ json: Any, keypath: String? = nil) throws -> [T] {
59+
do {
60+
guard let array = resourceData(from: json, keypath: keypath) as? [Any] else {
61+
return [T]()
62+
}
63+
return try array.map {
64+
try T.decode($0)
65+
}.compactMap { $0 }
66+
} catch (let error) {
67+
throw error
68+
}
69+
}
70+
71+
public func toModels<T: Decodable>(_ json: Any, keypath: String? = nil) throws -> [T] {
72+
do {
73+
guard let array = resourceData(from: json, keypath: keypath) as? [Any] else {
74+
return [T]()
75+
}
76+
return try array.map { jsonObject in
77+
let decoder = jsonDecoderFactory?() ?? JSONDecoder()
78+
let data = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
79+
let model = try decoder.decode(T.self, from: data)
80+
return model
81+
}.compactMap { $0 }
82+
} catch (let error) {
83+
throw error
84+
}
85+
}
86+
87+
private func resourceData(from json: Any, keypath: String?) -> Any {
88+
if let keypath = keypath, !keypath.isEmpty, let dic = json as? [String: Any], let val = dic[keypath] {
89+
return val is NSNull ? json : val
90+
}
91+
return json
92+
}
3593
}
3694

0 commit comments

Comments
 (0)