Use this document to help you understand how to update between major versions of the library. We test upgrade paths when we ramp major versions and do our best to have the compiler help make a useful upgrade experience.
Our directions are written for only 1 major version upgrade at a time, as we have found that to be the best experience.
V4 -> V5
Our approach to a SwiftUI API drastically changed. This new API is much more idiomatic and natural feeling when using SwiftUI. Additionally, it enables a series of new features. Previously, you used thenProceed(with:)
and WorkflowLauncher
to launch a workflow in SwiftUI. You now use WorkflowItem
and WorkflowView
, respectively. If you need more than 10 WorkflowItem
in your workflow, use WorkflowGroup
similar to Group
for other SwiftUI views.
// OLD
WorkflowLauncher(isLaunched: .constant(true)) {
thenProceed(with: FirstView.self) {
thenProceed(with: SecondView.self)
}
}
// NEW
WorkflowView {
WorkflowItem(FirstView.self) // This view is shown first
WorkflowItem(SecondView.self) // After proceeding, this view is shown
}
To transition from the old API, replace your calls to WorkflowLauncher
with WorkflowView
. Also note that startingArgs
has changed to launchingWith
. So the full signature changes from WorkflowLauncher(isLaunched: .constant(true), startingArgs: "someArgs")
to WorkflowView(isLaunched: .constant(true), launchingWith: "someArgs")
.
WorkflowView
's initializer defaults isLaunched
to .constant(true)
meaning you can exclude that parameter and just use WorkflowView(launchingWith: "someArgs")
V3 -> V4
The library changed its name from "Workflow" to "SwiftCurrent". This change was an important step for us, because it helps with SEO and gives people a sense that the library isn't just some generic thing slapped together.
Update your Podfile
to replace instances of DynamicWorkflow
with SwiftCurrent
# pod 'DynamicWorkflow' # OLD
pod 'SwiftCurrent' # NEW
Then update your import statements
// import Workflow // OLD
import SwiftCurrent // NEW
Update your URL in Xcode or your Package.swift
file to the new one, for example:
.package(url: "https://github.com/wwt/SwiftCurrent.git", .upToNextMajor(from: "4.0.0")),
Then update your imports from:
// import Workflow // OLD
import SwiftCurrent // NEW
// import WorkflowUIKit // OLD
import SwiftCurrent_UIKit // NEW
V2 -> V3
NOTE: We support both SwiftPM and CocoaPods now, pick whichever suits your needs best. The primary difference is that SwiftPM has different import
statements for import Workflow
and import WorkflowUIKit
, CocoaPods just uses import Workflow
.
- Update Podfile to:
pod 'DynamicWorkflow/UIKit'
- run a
pod install
- Your import statements will change from
import DynamicWorkflow
toimport Workflow
There is now a protocol for those using Storyboards called StoryboardLoadable. See the docs for more info.
IMPORTANT: StoryboardLoadable
has a minimum requirement of iOS 13. Be a little cautious of the Xcode fix-it here, it'll encourage you to add an @available
attribute, or it may tell you to implement _factory
methods. This is not correct, instead if you plan on using StoryboardLoadable
you should just set your minimum iOS target to 13, otherwise you've gotta hand roll something. The implementation of StoryboardLoadable
may help with hand rolling if that is what you decide to do.
Please review the FlowRepresentable docs to see the changes made there.
The static instance()
method is no longer required, instead a FlowRepresentable
now has a dedicated initializer, if the WorkflowInput
has a value you need init(with args: WorkflowInput)
. If WorkflowInput
is Never
you simply need init()
If you were using UIWorkflowItem<I>
, it has changed to UIWorkflowItem<I, O>
where I
is your input type and O
is your output type. See the docs for more info.
Update shouldLoad methods as they are no longer mutating, nor do they take in parameters. If you were doing any initializations during shouldLoad, that initialization should now happen in the initializer. If you were requiring parameters to be passed into shouldLoad those should now be part of initialization and referenced on the object in shouldLoad.
We no longer allow empty workflows, so if you instantiated a workflow like this:
Workflow()
.thenProceed(with: EnterAddressViewController.self)
Then you will need to update it to this:
Workflow(EnterAddressViewController.self)
This change was critical to allowing Type Safety within a Workflow.
They now take an AnyWorkflow.PassedArgs
type to help consumers of the library differentiate between no arguments being passed, and nil being passed explicitly. So you go from this:
// OLD
let workflow = ...
launchInto(Workflow(workflow) { [weak self] order in // order is an Any?
workflow.abandon()
self?.proceedInWorkflow(order)
}
To this:
// NEW
let workflow = ...
launchInto(Workflow(EnterAddressViewController.self) { [weak self] passedArgs in // passedArgs is an AnyWorkflow.PassedArgs
workflow.abandon()
guard case .args(let order as Order) = passedArgs else { return } // type safety!
self?.proceedInWorkflow(order)
}
You used to be able to re-assign proceedInWorkflow
to assert it was called with the args you expected, this has now slightly changed.
To get the exact behavior as before use _proceedInWorkflow
to re-assign that closure.
There's also proceedInWorkflowStorage
which gives you the AnyWorkflow.PassedArgs
used when proceedInWorkflow
was called.
If you were using some of the methods from our WorkflowExampleTests please look at how they're set up now, they're drastically different.