Skip to content

Commit d5bed2d

Browse files
committed
add threading assertions/checks
1 parent 5dece3c commit d5bed2d

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

AdyenNetworking/APIClient/APIClient.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public final class APIClient: APIClientProtocol {
109109
self.urlSession = URLSession(
110110
configuration: configuration ?? Self.buildDefaultConfiguration(),
111111
delegate: urlSessionDelegate,
112-
delegateQueue: .main
112+
delegateQueue: nil
113113
)
114114
self.responseValidator = responseValidator
115115
self.coder = coder
@@ -136,10 +136,14 @@ public final class APIClient: APIClientProtocol {
136136
}
137137
}
138138

139-
completionHandler(result)
139+
DispatchQueue.main.sync {
140+
completionHandler(result)
141+
}
140142
}.resume()
141143
} catch {
142-
completionHandler(.failure(error))
144+
DispatchQueue.main.sync {
145+
completionHandler(.failure(error))
146+
}
143147
}
144148
}
145149

@@ -148,15 +152,22 @@ public final class APIClient: APIClientProtocol {
148152
completionHandler: @escaping CompletionHandler<R.ResponseType>
149153
) where R: Request, R.ResponseType == DownloadResponse {
150154
do {
151-
urlSession.downloadTask(with: try buildUrlRequest(from: request)) { [weak self] result in
155+
urlSession.downloadTask(with: try buildUrlRequest(from: request)) { [weak self]
156+
result in
157+
assert(!Thread.isMainThread, "Should not be running on main thread!!")
152158
guard let self = self else { return }
153159
let result = result
154160
.flatMap { response in .init(catching: { try self.handle(response, request) }) }
155161
.map(\.responseBody)
156-
completionHandler(result)
162+
163+
DispatchQueue.main.sync {
164+
completionHandler(result)
165+
}
157166
}.resume()
158167
} catch {
159-
completionHandler(.failure(error))
168+
DispatchQueue.main.sync {
169+
completionHandler(.failure(error))
170+
}
160171
}
161172
}
162173

@@ -224,11 +235,13 @@ public final class APIClient: APIClientProtocol {
224235

225236

226237
try DispatchQueue.global(qos: .default).sync {
238+
assert(!Thread.isMainThread, "Should not be running on main thread!!")
227239
if let data = try? Data(contentsOf: result.url) {
228240
try responseValidator?.validate(data, for: request, with: result.headers)
229241
}
230242
}
231243

244+
assert(!Thread.isMainThread, "Should not be running on main thread!!")
232245
return HTTPResponse(
233246
headers: result.headers,
234247
statusCode: result.statusCode,

Networking Demo AppTests/APIClientTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,15 @@ class APIClientTests: XCTestCase {
284284
let downloadProgressExpectation = expectation(description: "Expect download progress to reach 100%.")
285285

286286
let request = TestAsyncDownloadRequest { progress in
287+
XCTAssertFalse(Thread.isMainThread, "Shouldn't be on main thread")
287288
if progress == 1.0 {
288289
downloadProgressExpectation.fulfill()
289290
}
290291
print("Download progress: \(progress)")
291292
}
292293
let mockValidator = MockResponseValidator()
293294
mockValidator.onValidated = {
295+
XCTAssertFalse(Thread.isMainThread, "Shouldn't be on main thread")
294296
responseValidationException.fulfill()
295297
throw ValidationError.invalidResponse
296298
}
@@ -304,6 +306,31 @@ class APIClientTests: XCTestCase {
304306
}
305307
await waitForExpectations(timeout: 10, handler: nil)
306308
}
309+
310+
// todo remove
311+
func testDownloadThreading() throws {
312+
let apiClientExpectation = expectation(description: "Expect api client to download image file.")
313+
let request = TestDownloadRequest()
314+
let api = APIClient(apiContext: SimpleAPIContext())
315+
let fileManager = FileManager.default
316+
317+
api.perform(request) { result in
318+
switch result {
319+
case .success(let downloadResponse):
320+
do {
321+
let image = UIImage(data: try Data(contentsOf: downloadResponse.url))
322+
XCTAssertNotNil(image)
323+
try fileManager.removeItem(at: downloadResponse.url)
324+
apiClientExpectation.fulfill()
325+
} catch {
326+
XCTFail(error.localizedDescription)
327+
}
328+
case let .failure(error):
329+
XCTFail(error.localizedDescription)
330+
}
331+
}
332+
waitForExpectations(timeout: 10, handler: nil)
333+
}
307334
}
308335

309336
enum ValidationError: Error {

0 commit comments

Comments
 (0)