Skip to content
This repository was archived by the owner on Sep 30, 2025. It is now read-only.

Commit 3ec513e

Browse files
authored
Merge pull request #202 from kmcbride/swift-request-management
Swift: Defer request storage until execution
2 parents 867c0a3 + 54b1f3a commit 3ec513e

File tree

3 files changed

+57
-34
lines changed

3 files changed

+57
-34
lines changed

Sources/SPTDataLoaderSwift/DataLoaderWrapper.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@ final class DataLoaderWrapper: NSObject {
3737
extension DataLoaderWrapper: DataLoader {
3838
func request(_ url: URL, sourceIdentifier: String?) -> Request {
3939
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: sourceIdentifier)
40-
let request = Request(request: sptRequest) { [dataLoader] in
41-
return dataLoader.perform(sptRequest)
42-
}
40+
let request = Request(request: sptRequest) { [weak self] request in
41+
guard let self = self else {
42+
return nil
43+
}
4344

44-
accessLock.sync {
45-
requests[sptRequest.uniqueIdentifier] = request
45+
self.accessLock.sync {
46+
self.requests[sptRequest.uniqueIdentifier] = request
47+
}
48+
49+
return self.dataLoader.perform(sptRequest)
4650
}
4751

4852
return request

Sources/SPTDataLoaderSwift/Request.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public typealias ResponseValidator = (SPTDataLoaderResponse) throws -> Void
3434
/// existing value.
3535
public final class Request {
3636
private let request: SPTDataLoaderRequest
37-
private let executionHandler: () -> SPTDataLoaderCancellationToken?
37+
private let executionHandler: (Request) -> SPTDataLoaderCancellationToken?
3838

39-
init(request: SPTDataLoaderRequest, executionHandler: @escaping () -> SPTDataLoaderCancellationToken?) {
39+
init(request: SPTDataLoaderRequest, executionHandler: @escaping (Request) -> SPTDataLoaderCancellationToken?) {
4040
self.request = request
4141
self.executionHandler = executionHandler
4242
}
@@ -71,7 +71,7 @@ public final class Request {
7171
accessLock.sync {
7272
switch state {
7373
case .initialized:
74-
if let token = executionHandler() {
74+
if let token = executionHandler(self) {
7575
responseHandlers.append(responseHandler)
7676
state = .executed(token: token)
7777
} else {

Tests/SPTDataLoaderSwift/RequestTest.swift

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class RequestTest: XCTestCase {
3232
let url = try XCTUnwrap(URL(string: "https://foo.bar/baz.json"))
3333
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
3434

35-
let request = Request(request: sptRequest) {
35+
let request = Request(request: sptRequest) { _ in
3636
return CancellationTokenFake()
3737
}
3838

@@ -48,7 +48,7 @@ class RequestTest: XCTestCase {
4848
let url = try XCTUnwrap(URL(string: "https://foo.bar/baz.json"))
4949
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
5050

51-
let request = Request(request: sptRequest) {
51+
let request = Request(request: sptRequest) { _ in
5252
return CancellationTokenFake()
5353
}
5454

@@ -68,7 +68,7 @@ class RequestTest: XCTestCase {
6868
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
6969
let cancellationTokenMock = CancellationTokenFake()
7070

71-
let request = Request(request: sptRequest) {
71+
let request = Request(request: sptRequest) { _ in
7272
return cancellationTokenMock
7373
}
7474

@@ -81,6 +81,25 @@ class RequestTest: XCTestCase {
8181
XCTAssertTrue(cancellationTokenMock.isCancelled)
8282
}
8383

84+
// MARK: Execution
85+
86+
func test_executionHandler_shouldReceiveRequestInstance_whenCalled() throws {
87+
// Given
88+
let url = try XCTUnwrap(URL(string: "https://foo.bar/baz.json"))
89+
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
90+
91+
// When
92+
var executedRequest: Request?
93+
let request = Request(request: sptRequest) { request in
94+
executedRequest = request
95+
return CancellationTokenFake()
96+
}
97+
request.addResponseHandler { _ in }
98+
99+
// Then
100+
XCTAssertTrue(request === executedRequest)
101+
}
102+
84103
// MARK: Response Validators
85104

86105
func test_responseValidator_shouldNotExecute_whenResponseContainsError() throws {
@@ -89,7 +108,7 @@ class RequestTest: XCTestCase {
89108
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
90109
let responseFake = FakeDataLoaderResponse(request: sptRequest, error: TestError.foo)
91110

92-
let request = Request(request: sptRequest) {
111+
let request = Request(request: sptRequest) { _ in
93112
return CancellationTokenFake()
94113
}
95114

@@ -111,7 +130,7 @@ class RequestTest: XCTestCase {
111130
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
112131
let responseFake = FakeDataLoaderResponse(request: sptRequest)
113132

114-
let request = Request(request: sptRequest) {
133+
let request = Request(request: sptRequest) { _ in
115134
return CancellationTokenFake()
116135
}
117136

@@ -134,7 +153,7 @@ class RequestTest: XCTestCase {
134153
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
135154
let responseFake = FakeDataLoaderResponse(request: sptRequest)
136155

137-
let request = Request(request: sptRequest) {
156+
let request = Request(request: sptRequest) { _ in
138157
return CancellationTokenFake()
139158
}
140159

@@ -166,7 +185,7 @@ class RequestTest: XCTestCase {
166185
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
167186
let responseFake = FakeDataLoaderResponse(request: sptRequest)
168187

169-
let request = Request(request: sptRequest) {
188+
let request = Request(request: sptRequest) { _ in
170189
return nil
171190
}
172191

@@ -190,7 +209,7 @@ class RequestTest: XCTestCase {
190209
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
191210
let responseFake = FakeDataLoaderResponse(request: sptRequest)
192211

193-
let request = Request(request: sptRequest) {
212+
let request = Request(request: sptRequest) { _ in
194213
return CancellationTokenFake()
195214
}
196215

@@ -210,7 +229,7 @@ class RequestTest: XCTestCase {
210229
let sptRequest = SPTDataLoaderRequest(url: url, sourceIdentifier: nil)
211230
let responseFake = FakeDataLoaderResponse(request: sptRequest)
212231

213-
let request = Request(request: sptRequest) {
232+
let request = Request(request: sptRequest) { _ in
214233
return CancellationTokenFake()
215234
}
216235

@@ -231,7 +250,7 @@ class RequestTest: XCTestCase {
231250
let responseFake = FakeDataLoaderResponse(request: sptRequest, error: TestError.foo)
232251

233252
var requestCount = 0
234-
let request = Request(request: sptRequest) {
253+
let request = Request(request: sptRequest) { _ in
235254
requestCount += 1
236255
return CancellationTokenFake()
237256
}
@@ -256,7 +275,7 @@ class RequestTest: XCTestCase {
256275
let responseFake = FakeDataLoaderResponse(request: sptRequest, error: TestError.foo)
257276

258277
var requestCount = 0
259-
let request = Request(request: sptRequest) {
278+
let request = Request(request: sptRequest) { _ in
260279
requestCount += 1
261280
return CancellationTokenFake()
262281
}
@@ -281,7 +300,7 @@ class RequestTest: XCTestCase {
281300
let responseFake = FakeDataLoaderResponse(request: sptRequest)
282301

283302
var requestCount = 0
284-
let request = Request(request: sptRequest) {
303+
let request = Request(request: sptRequest) { _ in
285304
requestCount += 1
286305
return CancellationTokenFake()
287306
}
@@ -309,7 +328,7 @@ class RequestTest: XCTestCase {
309328

310329
// When
311330
var response: Response<Void, Error>?
312-
Request(request: sptRequest) {
331+
Request(request: sptRequest) { _ in
313332
return CancellationTokenFake()
314333
}.validate { _ in
315334
throw TestError.foo
@@ -335,7 +354,7 @@ class RequestTest: XCTestCase {
335354

336355
// When
337356
var response: Response<Void, Error>?
338-
Request(request: sptRequest) {
357+
Request(request: sptRequest) { _ in
339358
return CancellationTokenFake()
340359
}.response {
341360
response = $0
@@ -361,7 +380,7 @@ class RequestTest: XCTestCase {
361380

362381
// When
363382
var response: Response<Data, Error>?
364-
Request(request: sptRequest) {
383+
Request(request: sptRequest) { _ in
365384
return CancellationTokenFake()
366385
}.responseData {
367386
response = $0
@@ -384,7 +403,7 @@ class RequestTest: XCTestCase {
384403

385404
// When
386405
var response: Response<Data, Error>?
387-
Request(request: sptRequest) {
406+
Request(request: sptRequest) { _ in
388407
return CancellationTokenFake()
389408
}.responseData {
390409
response = $0
@@ -408,7 +427,7 @@ class RequestTest: XCTestCase {
408427

409428
// When
410429
var response: Response<Data, Error>?
411-
Request(request: sptRequest) {
430+
Request(request: sptRequest) { _ in
412431
return CancellationTokenFake()
413432
}.responseData {
414433
response = $0
@@ -433,7 +452,7 @@ class RequestTest: XCTestCase {
433452

434453
// When
435454
var response: Response<TestDecodable, Error>?
436-
Request(request: sptRequest) {
455+
Request(request: sptRequest) { _ in
437456
return CancellationTokenFake()
438457
}.validate { _ in
439458
throw TestError.foo
@@ -459,7 +478,7 @@ class RequestTest: XCTestCase {
459478

460479
// When
461480
var response: Response<TestDecodable, Error>?
462-
Request(request: sptRequest) {
481+
Request(request: sptRequest) { _ in
463482
return CancellationTokenFake()
464483
}.responseDecodable {
465484
response = $0
@@ -483,7 +502,7 @@ class RequestTest: XCTestCase {
483502

484503
// When
485504
var response: Response<TestDecodable, Error>?
486-
Request(request: sptRequest) {
505+
Request(request: sptRequest) { _ in
487506
return CancellationTokenFake()
488507
}.responseDecodable {
489508
response = $0
@@ -508,7 +527,7 @@ class RequestTest: XCTestCase {
508527

509528
// When
510529
var response: Response<Any, Error>?
511-
Request(request: sptRequest) {
530+
Request(request: sptRequest) { _ in
512531
return CancellationTokenFake()
513532
}.validate { _ in
514533
throw TestError.foo
@@ -534,7 +553,7 @@ class RequestTest: XCTestCase {
534553

535554
// When
536555
var response: Response<Any, Error>?
537-
Request(request: sptRequest) {
556+
Request(request: sptRequest) { _ in
538557
return CancellationTokenFake()
539558
}.responseJSON {
540559
response = $0
@@ -558,7 +577,7 @@ class RequestTest: XCTestCase {
558577

559578
// When
560579
var response: Response<Any, Error>?
561-
Request(request: sptRequest) {
580+
Request(request: sptRequest) { _ in
562581
return CancellationTokenFake()
563582
}.responseJSON {
564583
response = $0
@@ -583,7 +602,7 @@ class RequestTest: XCTestCase {
583602

584603
// When
585604
var response: Response<String, Error>?
586-
Request(request: sptRequest) {
605+
Request(request: sptRequest) { _ in
587606
return CancellationTokenFake()
588607
}.validate { _ in
589608
throw TestError.foo
@@ -608,7 +627,7 @@ class RequestTest: XCTestCase {
608627

609628
// When
610629
var response: Response<String, Error>?
611-
Request(request: sptRequest) {
630+
Request(request: sptRequest) { _ in
612631
return CancellationTokenFake()
613632
}.responseSerializable(serializer: TestSerializer()) {
614633
response = $0
@@ -632,7 +651,7 @@ class RequestTest: XCTestCase {
632651

633652
// When
634653
var response: Response<String, Error>?
635-
Request(request: sptRequest) {
654+
Request(request: sptRequest) { _ in
636655
return CancellationTokenFake()
637656
}.responseSerializable(serializer: TestSerializer()) {
638657
response = $0

0 commit comments

Comments
 (0)