Skip to content

chore: Migrate core Workflow module off of ReactiveSwift#392

Merged
amorde merged 1 commit into
mainfrom
amorde/workflow-migrate-reactiveswift
Jul 17, 2026
Merged

chore: Migrate core Workflow module off of ReactiveSwift#392
amorde merged 1 commit into
mainfrom
amorde/workflow-migrate-reactiveswift

Conversation

@amorde

@amorde amorde commented Jul 15, 2026

Copy link
Copy Markdown
Member

Changes

Remove ReactiveSwift usage from the core Workflow and WorkflowUI modules.

The only usages there were for emitting outputs from WorkflowHosts to external consumers. The internal implementation of Workflow itself did not use ReactiveSwift at all.

WorkflowHost API changes:

- public let rendering: Property<WorkflowType.Rendering>
+ public var rendering: WorkflowType.Rendering { get }

+ public var renderingPublisher: AnyPublisher<WorkflowType.Rendering, Never>

- public var output: Signal<WorkflowType.Output, Never> { get }
+ public var outputPublisher: AnyPublisher<WorkflowType.Output, Never> { get }

WorkflowHostingController API changes:

- public var output: Signal<Output, Never> { get }
+ public var outputPublisher: AnyPublisher<Output, Never> { get }

Checklist

  • Unit Tests
  • UI Tests
  • Snapshot Tests (iOS only)
  • I have made corresponding changes to the documentation

@amorde
amorde force-pushed the amorde/workflow-migrate-reactiveswift branch 2 times, most recently from 7a76782 to f5021fb Compare July 15, 2026 21:48
@amorde
amorde marked this pull request as ready for review July 16, 2026 17:48
@amorde
amorde requested review from a team as code owners July 16, 2026 17:48
Comment thread Workflow/Sources/WorkflowHost.swift Outdated
/// A publisher of the `Rendering` values produced by the root workflow in the hierarchy. Emits a new value
/// after each render pass that occurs following subscription. Use `rendering` to read the current value.
public var renderingPublisher: AnyPublisher<WorkflowType.Rendering, Never> {
renderingSubject.dropFirst().eraseToAnyPublisher()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 renderingPublisher applying dropFirst() at the public boundary removes the atomic current-value-plus-future-updates behavior previously available from Property.producer. A render between reading rendering and subscribing becomes the subject’s current value and is then dropped. Could this return renderingSubject.eraseToAnyPublisher() and move .dropFirst() to WorkflowHostingController, which already consumes the initial rendering separately?

@amorde amorde Jul 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done because previously rendering.signal produced only changed renderings so without this all existing rendering.signal callers had to include .dropFirst(), which felt like a footgun for migrations.

Because ReactiveSwift's Property provides both options, we have to pick which behavior we adopt here:

  • Property.signal: Only emits updates
  • Property.producer: Emits current value + updates

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the producer semantics and letting callers use .dropFirst() feels more idiomatic (for example, matches the behavior of @Published properties), so I'll go with that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Eric! Matching the idiomatic @Published behavior feels like the best approach to me, too.

Comment thread Workflow/Sources/WorkflowHost.swift
Comment thread WorkflowUI/Sources/Hosting/WorkflowHostingController.swift Outdated

@johnnewman-square johnnewman-square left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good on my end. My agent just had a few suggestions.

@amorde
amorde force-pushed the amorde/workflow-migrate-reactiveswift branch from f5021fb to abb8c90 Compare July 17, 2026 17:01
@amorde
amorde force-pushed the amorde/workflow-migrate-reactiveswift branch from abb8c90 to 2cae038 Compare July 17, 2026 17:16

@johnnewman-square johnnewman-square left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making those tweaks.

@amorde
amorde merged commit d31ae0d into main Jul 17, 2026
14 checks passed
@amorde
amorde deleted the amorde/workflow-migrate-reactiveswift branch July 17, 2026 17:50
amorde added a commit to square/swift-modals that referenced this pull request Jul 17, 2026
Bump Workflow to 6.0 and address the ReactiveSwift removal from
square/workflow-swift#392
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants