Skip to content

Instantly share code, notes, and snippets.

@mbrandonw
Created December 10, 2019 12:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbrandonw/283a76e6cf2a714c2fe7627fc9400631 to your computer and use it in GitHub Desktop.
Save mbrandonw/283a76e6cf2a714c2fe7627fc9400631 to your computer and use it in GitHub Desktop.
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