diff --git a/swift/WorkflowUI/Sources/Container/ContainerViewController+AnyWorkflow.swift b/swift/WorkflowUI/Sources/Container/ContainerViewController+AnyWorkflow.swift new file mode 100644 index 000000000..87c70e600 --- /dev/null +++ b/swift/WorkflowUI/Sources/Container/ContainerViewController+AnyWorkflow.swift @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Square Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if canImport(UIKit) + +import Foundation +import Workflow + +extension ContainerViewController { + public convenience init( + workflow: W, + rootViewEnvironment: ViewEnvironment = .empty + ) where W.Rendering == ScreenType, W.Output == Output { + self.init(workflow: WrapperWorkflow(workflow), rootViewEnvironment: rootViewEnvironment) + } +} + +fileprivate struct WrapperWorkflow: Workflow { + typealias State = Void + typealias Output = Output + typealias Rendering = Rendering + + var wrapped: AnyWorkflow + + init(_ wrapped: W) where W.Output == Output, W.Rendering == Rendering { + self.wrapped = wrapped.asAnyWorkflow() + } + + func makeInitialState() -> State { + return () + } + + func workflowDidChange(from previousWorkflow: WrapperWorkflow, state: inout State) { + } + + func render(state: State, context: RenderContext) -> Rendering { + return wrapped + .mapOutput { AnyWorkflowAction(sendingOutput: $0) } + .rendered(with: context) + } +} + +#endif diff --git a/swift/WorkflowUI/Tests/ContainerViewControllerTests.swift b/swift/WorkflowUI/Tests/ContainerViewControllerTests.swift index af7cb373e..1865d0d54 100644 --- a/swift/WorkflowUI/Tests/ContainerViewControllerTests.swift +++ b/swift/WorkflowUI/Tests/ContainerViewControllerTests.swift @@ -95,6 +95,26 @@ class ContainerViewControllerTests: XCTestCase { disposable?.dispose() } + + func test_container_with_anyworkflow() { + + let (signal, observer) = Signal.pipe() + let workflow = MockWorkflow(subscription: signal) + let container = ContainerViewController(workflow: workflow.asAnyWorkflow()) + + let expectation = XCTestExpectation(description: "Output") + + let disposable = container.output.observeValues { value in + XCTAssertEqual(3, value) + expectation.fulfill() + } + + observer.send(value: 3) + + wait(for: [expectation], timeout: 1.0) + + disposable?.dispose() + } }