Skip to content

Commit 1ff4a45

Browse files
committed
[refactor]: Remove ReactiveSwift from Workflow public interface
BREAKING CHANGE: This changes the public interface of WorkflowHost and WorkflowHostingController. The rendering property is now a read only property of the Rendering There is a new renderingPublisher property for a Combine publisher for renderings The output Signal property has been removed and moved to an extension in WorkflowReactiveSwift There is a new outputPublisher property for a Combine publisher for output
1 parent 1d4ba78 commit 1ff4a45

File tree

21 files changed

+292
-251
lines changed

21 files changed

+292
-251
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ let package = Package(
7171
name: "Workflow",
7272
dependencies: [
7373
.product(name: "IssueReporting", package: "xctest-dynamic-overlay"),
74-
.product(name: "ReactiveSwift", package: "ReactiveSwift"),
7574
],
7675
path: "Workflow/Sources"
7776
),
77+
7878
.target(
7979
name: "WorkflowTesting",
8080
dependencies: [

Samples/Project.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,10 @@ let project = Project(
158158
.unitTest(
159159
for: "Workflow",
160160
sources: "../Workflow/Tests/**",
161-
dependencies: [.external(name: "Workflow")]
161+
dependencies: [
162+
.external(name: "ReactiveSwift"),
163+
.external(name: "Workflow"),
164+
]
162165
),
163166
.unitTest(
164167
for: "WorkflowTesting",

Samples/Tutorial/Frameworks/Tutorial5Complete/Tests/RootWorkflowTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class RootWorkflowTests: XCTestCase {
8787

8888
// First rendering is just the welcome screen. Update the name.
8989
do {
90-
let backStack = workflowHost.rendering.value
90+
let backStack = workflowHost.rendering
9191
XCTAssertEqual(1, backStack.items.count)
9292

9393
guard let welcomeScreen = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {
@@ -100,7 +100,7 @@ class RootWorkflowTests: XCTestCase {
100100

101101
// Log in and go to the todo list.
102102
do {
103-
let backStack = workflowHost.rendering.value
103+
let backStack = workflowHost.rendering
104104
XCTAssertEqual(1, backStack.items.count)
105105

106106
guard let welcomeScreen = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {
@@ -113,7 +113,7 @@ class RootWorkflowTests: XCTestCase {
113113

114114
// Expect the todo list to be rendered. Edit the first todo.
115115
do {
116-
let backStack = workflowHost.rendering.value
116+
let backStack = workflowHost.rendering
117117
XCTAssertEqual(2, backStack.items.count)
118118

119119
guard let _ = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {
@@ -134,7 +134,7 @@ class RootWorkflowTests: XCTestCase {
134134

135135
// Selected a todo to edit. Expect the todo edit screen.
136136
do {
137-
let backStack = workflowHost.rendering.value
137+
let backStack = workflowHost.rendering
138138
XCTAssertEqual(3, backStack.items.count)
139139

140140
guard let _ = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {
@@ -158,7 +158,7 @@ class RootWorkflowTests: XCTestCase {
158158

159159
// Save the selected todo.
160160
do {
161-
let backStack = workflowHost.rendering.value
161+
let backStack = workflowHost.rendering
162162
XCTAssertEqual(3, backStack.items.count)
163163

164164
guard let _ = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {
@@ -204,7 +204,7 @@ class RootWorkflowTests: XCTestCase {
204204

205205
// Expect the todo list. Validate the title was updated.
206206
do {
207-
let backStack = workflowHost.rendering.value
207+
let backStack = workflowHost.rendering
208208
XCTAssertEqual(2, backStack.items.count)
209209

210210
guard let _ = backStack.items[0].screen.wrappedScreen as? WelcomeScreen else {

Workflow/Sources/WorkflowHost.swift

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import Dispatch
18-
import ReactiveSwift
18+
import Combine
1919

2020
/// Defines a type that receives debug information about a running workflow hierarchy.
2121
public protocol WorkflowDebugger {
@@ -31,18 +31,31 @@ public protocol WorkflowDebugger {
3131
func didUpdate(snapshot: WorkflowHierarchyDebugSnapshot, updateInfo: WorkflowUpdateDebugInfo)
3232
}
3333

34-
/// Manages an active workflow hierarchy.
35-
public final class WorkflowHost<WorkflowType: Workflow> {
36-
private let (outputEvent, outputEventObserver) = Signal<WorkflowType.Output, Never>.pipe()
34+
/// This protocol provides a way for an output extension to be added to both WorkflowHost and WorkflowHostingController in WorkflowReactiveSwift.
35+
public protocol _WorkflowOutputPublisher {
36+
associatedtype Output
37+
38+
var outputPublisher: AnyPublisher<Output, Never> { get }
39+
}
3740

41+
/// Manages an active workflow hierarchy.
42+
public final class WorkflowHost<WorkflowType: Workflow>: _WorkflowOutputPublisher {
3843
// @testable
3944
let rootNode: WorkflowNode<WorkflowType>
4045

41-
private let mutableRendering: MutableProperty<WorkflowType.Rendering>
46+
private let renderingSubject: CurrentValueSubject<WorkflowType.Rendering, Never>
47+
private let outputSubject = PassthroughSubject<WorkflowType.Output, Never>()
4248

4349
/// Represents the `Rendering` produced by the root workflow in the hierarchy. New `Rendering` values are produced
4450
/// as state transitions occur within the hierarchy.
45-
public let rendering: Property<WorkflowType.Rendering>
51+
public var rendering: WorkflowType.Rendering {
52+
renderingSubject.value
53+
}
54+
55+
/// A Publisher containing rendering events produced by the root workflow in the hierarchy.
56+
public var renderingPublisher: AnyPublisher<WorkflowType.Rendering, Never> {
57+
renderingSubject.eraseToAnyPublisher()
58+
}
4659

4760
/// Context object to pass down to descendant nodes in the tree.
4861
let context: HostContext
@@ -88,8 +101,8 @@ public final class WorkflowHost<WorkflowType: Workflow> {
88101
parentSession: nil
89102
)
90103

91-
self.mutableRendering = MutableProperty(rootNode.render())
92-
self.rendering = Property(mutableRendering)
104+
self.renderingSubject = CurrentValueSubject(rootNode.render())
105+
93106
rootNode.enableEvents()
94107

95108
debugger?.didEnterInitialState(snapshot: rootNode.makeDebugSnapshot())
@@ -130,12 +143,12 @@ public final class WorkflowHost<WorkflowType: Workflow> {
130143
private func handle(output: WorkflowNode<WorkflowType>.Output) {
131144
let shouldRender = !shouldSkipRenderForOutput(output)
132145
if shouldRender {
133-
mutableRendering.value = rootNode.render()
146+
renderingSubject.send(rootNode.render())
134147
}
135148

136149
// Always emit an output, regardless of whether a render occurs
137150
if let outputEvent = output.outputEvent {
138-
outputEventObserver.send(value: outputEvent)
151+
outputSubject.send(outputEvent)
139152
}
140153

141154
debugger?.didUpdate(
@@ -149,9 +162,9 @@ public final class WorkflowHost<WorkflowType: Workflow> {
149162
}
150163
}
151164

152-
/// A signal containing output events emitted by the root workflow in the hierarchy.
153-
public var output: Signal<WorkflowType.Output, Never> {
154-
outputEvent
165+
/// A publisher containing output events emitted by the root workflow in the hierarchy.
166+
public var outputPublisher: AnyPublisher<WorkflowType.Output, Never> {
167+
outputSubject.eraseToAnyPublisher()
155168
}
156169
}
157170

Workflow/Tests/AnyWorkflowTests.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import ReactiveSwift
17+
import Combine
1818
import XCTest
1919
@testable import Workflow
2020

@@ -40,19 +40,21 @@ public class AnyWorkflowTests: XCTestCase {
4040
let host = WorkflowHost(workflow: OnOutputWorkflow())
4141

4242
let renderingExpectation = expectation(description: "Waiting for rendering")
43-
host.rendering.producer.startWithValues { rendering in
43+
let cancellable = host.renderingPublisher.sink { rendering in
4444
if rendering {
4545
renderingExpectation.fulfill()
4646
}
4747
}
4848

4949
let outputExpectation = expectation(description: "Waiting for output")
50-
host.output.observeValues { output in
50+
let outputCancellable = host.outputPublisher.sink { output in
5151
if output {
5252
outputExpectation.fulfill()
5353
}
5454
}
5555
wait(for: [renderingExpectation, outputExpectation], timeout: 1)
56+
cancellable.cancel()
57+
outputCancellable.cancel()
5658
}
5759

5860
func testOnlyWrapsOnce() {

0 commit comments

Comments
 (0)