From 1a6e8d3cc0e61511661da4867b0e0f91f5842456 Mon Sep 17 00:00:00 2001 From: Westin Newell Date: Thu, 12 Jan 2023 16:05:53 -0800 Subject: [PATCH] Add support for observing AnyWorkflowConvertible to WorkflowHost --- Workflow/Sources/WorkflowHost.swift | 37 +++++++++++++++++++ .../Hosting/WorkflowHostingController.swift | 25 +------------ 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/Workflow/Sources/WorkflowHost.swift b/Workflow/Sources/WorkflowHost.swift index 2cab79e41..5b9ee43e0 100644 --- a/Workflow/Sources/WorkflowHost.swift +++ b/Workflow/Sources/WorkflowHost.swift @@ -100,3 +100,40 @@ public final class WorkflowHost { return outputEvent } } + +extension WorkflowHost { + /// Initializes a new host with the given workflow at the root. + /// + /// - Parameter workflow: The root workflow in the hierarchy + /// - Parameter debugger: An optional debugger. If provided, the host will notify the debugger of updates + /// + @_disfavoredOverload + public convenience init( + workflow: AnyWorkflowType, + debugger: WorkflowDebugger? = nil + ) where WorkflowType == AnyWorkflowWrapper { + self.init(workflow: AnyWorkflowWrapper(workflow), debugger: debugger) + } +} + +public typealias AnyWorkflowHost = WorkflowHost> + +/// A wrapper around an AnyWorkflow that allows consumers to create a WorkflowHost from an +/// `AnyWorkflowConvertible`. +public struct AnyWorkflowWrapper: Workflow { + public typealias State = Void + public typealias Output = Output + public typealias Rendering = Rendering + + var wrapped: AnyWorkflow + + public init(_ wrapped: W) where W.Rendering == Rendering, W.Output == Output { + self.wrapped = wrapped.asAnyWorkflow() + } + + public func render(state: State, context: RenderContext) -> Rendering { + return wrapped + .mapOutput { AnyWorkflowAction(sendingOutput: $0) } + .rendered(in: context) + } +} diff --git a/WorkflowUI/Sources/Hosting/WorkflowHostingController.swift b/WorkflowUI/Sources/Hosting/WorkflowHostingController.swift index 761364796..ae1e75bfd 100644 --- a/WorkflowUI/Sources/Hosting/WorkflowHostingController.swift +++ b/WorkflowUI/Sources/Hosting/WorkflowHostingController.swift @@ -29,7 +29,7 @@ private(set) var rootViewController: UIViewController - private let workflowHost: WorkflowHost> + private let workflowHost: AnyWorkflowHost private let (lifetime, token) = Lifetime.make() @@ -40,7 +40,7 @@ } public init(workflow: W, rootViewEnvironment: ViewEnvironment = .empty) where W.Rendering == ScreenType, W.Output == Output { - self.workflowHost = WorkflowHost(workflow: RootWorkflow(workflow)) + self.workflowHost = WorkflowHost(workflow: workflow) self.rootViewController = workflowHost .rendering @@ -144,27 +144,6 @@ } } - /// Wrapper around an AnyWorkflow that allows us to have a concrete - /// WorkflowHost without WorkflowHostingController itself being generic - /// around a Workflow. - fileprivate struct RootWorkflow: Workflow { - typealias State = Void - typealias Output = Output - typealias Rendering = Rendering - - var wrapped: AnyWorkflow - - init(_ wrapped: W) where W.Rendering == Rendering, W.Output == Output { - self.wrapped = wrapped.asAnyWorkflow() - } - - func render(state: State, context: RenderContext) -> Rendering { - return wrapped - .mapOutput { AnyWorkflowAction(sendingOutput: $0) } - .rendered(in: context) - } - } - @available(*, deprecated, renamed: "WorkflowHostingController") public typealias ContainerViewController = WorkflowHostingController