Created
December 10, 2019 12:22
-
-
Save mbrandonw/283a76e6cf2a714c2fe7627fc9400631 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/0084-testable-state-management-ergonomics/PrimeTime/ComposableArchitecture/ComposableArchitecture.swift b/0084-testable-state-management-ergonomics/PrimeTime/ComposableArchitecture/ComposableArchitecture.swift | |
index db4ab12..ab96c5f 100644 | |
--- a/0084-testable-state-management-ergonomics/PrimeTime/ComposableArchitecture/ComposableArchitecture.swift | |
+++ b/0084-testable-state-management-ergonomics/PrimeTime/ComposableArchitecture/ComposableArchitecture.swift | |
@@ -128,3 +128,24 @@ public func logging<Value, Action>( | |
}] + effects | |
} | |
} | |
+ | |
+ | |
+extension Publisher where Failure == Never { | |
+ public func cancellable<Id: Hashable>(id: Id) -> Effect<Output> { | |
+ return Deferred { () -> PassthroughSubject<Output, Failure> in | |
+ cancellables[id]?.cancel() | |
+ let subject = PassthroughSubject<Output, Failure>() | |
+ cancellables[id] = self.subscribe(subject) | |
+ return subject | |
+ } | |
+ .eraseToEffect() | |
+ } | |
+ | |
+ public static func cancel<Id: Hashable>(id: Id) -> Effect<Output> { | |
+ .fireAndForget { | |
+ cancellables[id]?.cancel() | |
+ } | |
+ } | |
+} | |
+ | |
+private var cancellables: [AnyHashable: AnyCancellable] = [:] | |
diff --git a/0084-testable-state-management-ergonomics/PrimeTime/Counter/Counter.swift b/0084-testable-state-management-ergonomics/PrimeTime/Counter/Counter.swift | |
index fb61f6c..4a0a770 100644 | |
--- a/0084-testable-state-management-ergonomics/PrimeTime/Counter/Counter.swift | |
+++ b/0084-testable-state-management-ergonomics/PrimeTime/Counter/Counter.swift | |
@@ -1,6 +1,7 @@ | |
import ComposableArchitecture | |
import PrimeModal | |
import SwiftUI | |
+import Combine | |
public enum CounterAction: Equatable { | |
case decrTapped | |
@@ -8,6 +9,7 @@ public enum CounterAction: Equatable { | |
case nthPrimeButtonTapped | |
case nthPrimeResponse(Int?) | |
case alertDismissButtonTapped | |
+ case receivedTimer | |
} | |
public typealias CounterState = ( | |
@@ -18,13 +20,25 @@ public typealias CounterState = ( | |
public func counterReducer(state: inout CounterState, action: CounterAction) -> [Effect<CounterAction>] { | |
switch action { | |
+ case .receivedTimer: | |
+ print("Timer received!") | |
+ return [] | |
+ | |
case .decrTapped: | |
state.count -= 1 | |
- return [] | |
+ return [ | |
+ .cancel(id: "timer") | |
+ ] | |
case .incrTapped: | |
state.count += 1 | |
- return [] | |
+ return [ | |
+ Timer.publish(every: 1, on: .main, in: .default) | |
+ .autoconnect() | |
+ .map { _ in CounterAction.receivedTimer } | |
+ .eraseToEffect() | |
+ .cancellable(id: "timer") | |
+ ] | |
case .nthPrimeButtonTapped: | |
state.isNthPrimeButtonDisabled = true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment