Skip to content

Commit 83e7557

Browse files
authored
Simplify Reusable Download Component (#756)
1 parent 3c51885 commit 83e7557

File tree

3 files changed

+11
-42
lines changed

3 files changed

+11
-42
lines changed

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

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import ComposableArchitecture
33
import Foundation
44

55
struct DownloadClient {
6-
var cancel: (AnyHashable) -> Effect<Never, Never>
7-
var download: (AnyHashable, URL) -> Effect<Action, Error>
6+
var download: (URL) -> Effect<Action, Error>
87

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

@@ -16,14 +15,7 @@ struct DownloadClient {
1615

1716
extension DownloadClient {
1817
static let live = DownloadClient(
19-
cancel: { id in
20-
.fireAndForget {
21-
dependencies[id]?.observation.invalidate()
22-
dependencies[id]?.task.cancel()
23-
dependencies[id] = nil
24-
}
25-
},
26-
download: { id, url in
18+
download: { url in
2719
.run { subscriber in
2820
let task = URLSession.shared.dataTask(with: url) { data, _, error in
2921
switch (data, error) {
@@ -41,26 +33,13 @@ extension DownloadClient {
4133
subscriber.send(.updateProgress(progress.fractionCompleted))
4234
}
4335

44-
dependencies[id] = Dependencies(
45-
observation: observation,
46-
task: task
47-
)
48-
4936
task.resume()
5037

5138
return AnyCancellable {
5239
observation.invalidate()
5340
task.cancel()
54-
dependencies[id] = nil
5541
}
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
@@ -60,8 +60,7 @@ extension Reducer {
6060
case .alert(.cancelButtonTapped):
6161
state.mode = .notDownloaded
6262
state.alert = nil
63-
return environment.downloadClient.cancel(state.id)
64-
.fireAndForget()
63+
return .cancel(id: state.id)
6564

6665
case .alert(.deleteButtonTapped):
6766
state.alert = nil
@@ -86,9 +85,10 @@ extension Reducer {
8685
case .notDownloaded:
8786
state.mode = .startingToDownload
8887
return environment.downloadClient
89-
.download(state.id, state.url)
88+
.download(state.url)
9089
.throttle(for: 1, scheduler: environment.mainQueue, latest: true)
9190
.catchToEffect(DownloadComponentAction.downloadClient)
91+
.cancellable(id: state.id)
9292

9393
case .startingToDownload:
9494
state.alert = cancelAlert

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.eraseToEffect() }
22+
downloadClient.download = { _ in self.downloadSubject.eraseToEffect() }
2323

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

5555
func testDownloadThrottling() {
5656
var downloadClient = DownloadClient.failing
57-
downloadClient.download = { _, _ in self.downloadSubject.eraseToEffect() }
57+
downloadClient.download = { _ in self.downloadSubject.eraseToEffect() }
5858

5959
let store = TestStore(
6060
initialState: DownloadComponentState(
@@ -94,10 +94,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
9494

9595
func testCancelDownloadFlow() {
9696
var downloadClient = DownloadClient.failing
97-
downloadClient.cancel = { _ in
98-
.fireAndForget { self.downloadSubject.send(completion: .finished) }
99-
}
100-
downloadClient.download = { _, _ in self.downloadSubject.eraseToEffect() }
97+
downloadClient.download = { _ in self.downloadSubject.eraseToEffect() }
10198

10299
let store = TestStore(
103100
initialState: DownloadComponentState(
@@ -134,10 +131,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
134131

135132
func testDownloadFinishesWhileTryingToCancel() {
136133
var downloadClient = DownloadClient.failing
137-
downloadClient.cancel = { _ in
138-
.fireAndForget { self.downloadSubject.send(completion: .finished) }
139-
}
140-
downloadClient.download = { _, _ in self.downloadSubject.eraseToEffect() }
134+
downloadClient.download = { _ in self.downloadSubject.eraseToEffect() }
141135

142136
let store = TestStore(
143137
initialState: DownloadComponentState(
@@ -175,10 +169,7 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
175169

176170
func testDeleteDownloadFlow() {
177171
var downloadClient = DownloadClient.failing
178-
downloadClient.cancel = { _ in
179-
.fireAndForget { self.downloadSubject.send(completion: .finished) }
180-
}
181-
downloadClient.download = { _, _ in self.downloadSubject.eraseToEffect() }
172+
downloadClient.download = { _ in self.downloadSubject.eraseToEffect() }
182173

183174
let store = TestStore(
184175
initialState: DownloadComponentState(
@@ -210,7 +201,6 @@ class ReusableComponentsDownloadComponentTests: XCTestCase {
210201

211202
extension DownloadClient {
212203
static let failing = Self(
213-
cancel: { _ in .failing("DownloadClient.cancel") },
214-
download: { _, _ in .failing("DownloadClient.download") }
204+
download: { _ in .failing("DownloadClient.download") }
215205
)
216206
}

0 commit comments

Comments
 (0)