Skip to content

Commit 8e32e15

Browse files
committed
Simplify Reusable Download Component (#756)
1 parent afb4ebd commit 8e32e15

File tree

4 files changed

+16
-46
lines changed

4 files changed

+16
-46
lines changed

Examples/CaseStudies/SwiftUICaseStudies/04-HigherOrderReducers-ResuableOfflineDownloads/DownloadClient.swift

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import Foundation
44
import ReactiveSwift
55

66
struct DownloadClient {
7-
var cancel: (AnyHashable) -> Effect<Never, Never>
8-
var download: (AnyHashable, URL) -> Effect<Action, Error>
7+
var download: (URL) -> Effect<Action, Error>
98

109
struct Error: Swift.Error, Equatable {}
1110

@@ -17,14 +16,7 @@ struct DownloadClient {
1716

1817
extension DownloadClient {
1918
static let live = DownloadClient(
20-
cancel: { id in
21-
.fireAndForget {
22-
dependencies[id]?.observation.invalidate()
23-
dependencies[id]?.task.cancel()
24-
dependencies[id] = nil
25-
}
26-
},
27-
download: { id, url in
19+
download: { url in
2820
.init { subscriber, lifetime in
2921
let task = URLSession.shared.dataTask(with: url) { data, _, error in
3022
switch (data, error) {
@@ -42,25 +34,12 @@ extension DownloadClient {
4234
subscriber.send(value: .updateProgress(progress.fractionCompleted))
4335
}
4436

45-
dependencies[id] = Dependencies(
46-
observation: observation,
47-
task: task
48-
)
49-
5037
lifetime += AnyDisposable {
5138
observation.invalidate()
5239
task.cancel()
53-
dependencies[id] = nil
5440
}
5541
task.resume()
5642
}
5743
}
5844
)
5945
}
60-
61-
private struct Dependencies {
62-
let observation: NSKeyValueObservation
63-
let task: URLSessionDataTask
64-
}
65-
66-
private var dependencies: [AnyHashable: Dependencies] = [:]

Examples/CaseStudies/SwiftUICaseStudies/04-HigherOrderReducers-ResuableOfflineDownloads/DownloadComponent.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ extension Reducer {
6161
case .alert(.cancelButtonTapped):
6262
state.mode = .notDownloaded
6363
state.alert = nil
64-
return environment.downloadClient.cancel(state.id)
65-
.fireAndForget()
64+
return .cancel(id: state.id)
6665

6766
case .alert(.deleteButtonTapped):
6867
state.alert = nil
@@ -87,9 +86,10 @@ extension Reducer {
8786
case .notDownloaded:
8887
state.mode = .startingToDownload
8988
return environment.downloadClient
90-
.download(state.id, state.url)
89+
.download(state.url)
9190
.throttle(1, on: environment.mainQueue)
9291
.catchToEffect(DownloadComponentAction.downloadClient)
92+
.cancellable(id: state.id)
9393

9494
case .startingToDownload:
9595
state.alert = cancelAlert

Examples/CaseStudies/SwiftUICaseStudiesTests/02-Effects-RefreshableTests.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ReactiveSwift
12
import ComposableArchitecture
23
import XCTest
34

@@ -10,7 +11,7 @@ class RefreshableTests: XCTestCase {
1011
reducer: refreshableReducer,
1112
environment: .init(
1213
fact: .init { .init(value: "\($0) is a good number.") },
13-
mainQueue: .immediate
14+
mainQueue: ImmediateScheduler()
1415
)
1516
)
1617

@@ -32,7 +33,7 @@ class RefreshableTests: XCTestCase {
3233
reducer: refreshableReducer,
3334
environment: .init(
3435
fact: .init { _ in .init(error: .init()) },
35-
mainQueue: .immediate
36+
mainQueue: ImmediateScheduler()
3637
)
3738
)
3839

@@ -48,14 +49,14 @@ class RefreshableTests: XCTestCase {
4849
}
4950

5051
func testCancellation() {
51-
let mainQueue = DispatchQueue.test
52+
let mainQueue = TestScheduler()
5253

5354
let store = TestStore(
5455
initialState: .init(),
5556
reducer: refreshableReducer,
5657
environment: .init(
5758
fact: .init { .init(value: "\($0) is a good number.") },
58-
mainQueue: mainQueue.eraseToAnyScheduler()
59+
mainQueue: mainQueue
5960
)
6061
)
6162

Examples/CaseStudies/SwiftUICaseStudiesTests/04-HigherOrderReducers-ReusableOfflineDownloadsTests.swift

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
1919

2020
func testDownloadFlow() {
2121
var downloadClient = DownloadClient.failing
22-
downloadClient.download = { _, _ in self.downloadSubject.output.producer }
22+
downloadClient.download = { _ in self.downloadSubject.output.producer }
2323

2424
let store = TestStore(
2525
initialState: DownloadComponentState(
@@ -55,7 +55,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
5555

5656
func testDownloadThrottling() {
5757
var downloadClient = DownloadClient.failing
58-
downloadClient.download = { _, _ in self.downloadSubject.output.producer }
58+
downloadClient.download = { _ in self.downloadSubject.output.producer }
5959

6060
let store = TestStore(
6161
initialState: DownloadComponentState(
@@ -95,10 +95,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
9595

9696
func testCancelDownloadFlow() {
9797
var downloadClient = DownloadClient.failing
98-
downloadClient.cancel = { _ in
99-
.fireAndForget { self.downloadSubject.input.sendCompleted() }
100-
}
101-
downloadClient.download = { _, _ in self.downloadSubject.output.producer }
98+
downloadClient.download = { _ in self.downloadSubject.output.producer }
10299

103100
let store = TestStore(
104101
initialState: DownloadComponentState(
@@ -135,10 +132,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
135132

136133
func testDownloadFinishesWhileTryingToCancel() {
137134
var downloadClient = DownloadClient.failing
138-
downloadClient.cancel = { _ in
139-
.fireAndForget { self.downloadSubject.input.sendCompleted() }
140-
}
141-
downloadClient.download = { _, _ in self.downloadSubject.output.producer }
135+
downloadClient.download = { _ in self.downloadSubject.output.producer }
142136

143137
let store = TestStore(
144138
initialState: DownloadComponentState(
@@ -177,10 +171,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
177171

178172
func testDeleteDownloadFlow() {
179173
var downloadClient = DownloadClient.failing
180-
downloadClient.cancel = { _ in
181-
.fireAndForget { self.downloadSubject.input.sendCompleted() }
182-
}
183-
downloadClient.download = { _, _ in self.downloadSubject.output.producer }
174+
downloadClient.download = { _ in self.downloadSubject.output.producer }
184175

185176
let store = TestStore(
186177
initialState: DownloadComponentState(
@@ -212,7 +203,6 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
212203

213204
extension DownloadClient {
214205
static let failing = Self(
215-
cancel: { _ in .failing("DownloadClient.cancel") },
216-
download: { _, _ in .failing("DownloadClient.download") }
206+
download: { _ in .failing("DownloadClient.download") }
217207
)
218208
}

0 commit comments

Comments
 (0)