Skip to content

Commit c2029a9

Browse files
Merge pull request #109 from dbsystel/async-await
Cancel support in Async/Await
2 parents 5aafb1d + e60d49d commit c2029a9

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

Source/NetworkService+Async.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,17 @@ public extension NetworkService {
2828
*/
2929
@discardableResult
3030
func request<Result>(_ resource: Resource<Result>) async throws -> (Result, HTTPURLResponse) {
31-
return try await withCheckedThrowingContinuation({ coninuation in
32-
request(resource: resource, onCompletionWithResponse: {
33-
coninuation.resume(with: $0)
31+
var task: NetworkTask?
32+
let cancel = { task?.cancel() }
33+
return try await withTaskCancellationHandler(operation: {
34+
try Task.checkCancellation()
35+
return try await withCheckedThrowingContinuation({ coninuation in
36+
task = request(resource: resource, onCompletionWithResponse: {
37+
coninuation.resume(with: $0)
38+
})
3439
})
40+
}, onCancel: {
41+
cancel()
3542
})
3643
}
3744

@@ -53,10 +60,17 @@ public extension NetworkService {
5360
*/
5461
@discardableResult
5562
func request<Result, E: Error>(_ resource: ResourceWithError<Result, E>) async throws -> (Result, HTTPURLResponse) {
56-
return try await withCheckedThrowingContinuation({ coninuation in
57-
request(resource: resource, onCompletionWithResponse: {
58-
coninuation.resume(with: $0)
63+
var task: NetworkTask?
64+
let cancel = { task?.cancel() }
65+
return try await withTaskCancellationHandler(operation: {
66+
try Task.checkCancellation()
67+
return try await withCheckedThrowingContinuation({ coninuation in
68+
task = request(resource: resource, onCompletionWithResponse: {
69+
coninuation.resume(with: $0)
70+
})
5971
})
72+
}, onCancel: {
73+
cancel()
6074
})
6175
}
6276

Tests/NetworkServiceTest.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,23 @@ class NetworkServiceTest: XCTestCase {
268268
XCTAssertTrue(error is NetworkError)
269269
}
270270
}
271+
272+
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
273+
func testGIVEN_aRequest_WHEN_requestWithAsyncResultAndResponseAndCancel_THEN_ShouldThwo() async {
274+
// GIVEN
275+
let error = NSError(domain: "", code: 0, userInfo: nil)
276+
networkAccess.changeMock(data: nil, response: nil, error: error)
277+
278+
//When
279+
let task = Task {
280+
try await networkService.request(resource)
281+
}
282+
task.cancel()
283+
let result = await task.result
284+
if case .failure(let error) = result, let networkError = error as? CancellationError {
285+
286+
} else {
287+
XCTFail("Schould throw")
288+
}
289+
}
271290
}

0 commit comments

Comments
 (0)