Closed Tyler-Keith-Thompson closed 2 years ago
Even hacky workarounds are proving difficult
For anybody who might also be stuck here's a horrible workaround:
struct HomeView_Previews: PreviewProvider {
struct WF: View {
var body: some View {
WorkflowLauncher(isLaunched: .constant(true)) {
thenProceed(with: HomeView.self)
.presentationType(.navigationLink)
}.embedInNavigationView()
}
}
static var previews: some View { WF() }
}
Closing because this is working and has been merged.
Please reopen. This was not merged to main. It isn't available for consumers because it was a breaking change
I'll reopen but I'm a little confused. I was able to see the ContentView in the SwiftUI sample rendering correctly while using the preview canvas. Unless you're saying that you can't write thenProceed
in the previewprovider, but I'm not sure why that would be a thing we'd want to do. My impression was that you just put the view into the previewprovider and if that rendered then you're good.
TL;DR: We want this for several reasons
FlowRepresentable
may not have an obvious initializer outside of WorkflowLauncher
depending on client set-upsApologies, you made a statement about being a little confused and got a dissertation back, but context matters are words are hard.
I'll start by referencing our design philosophy. Having an API that doesn't work for a key and critical part of SwiftUI feels wrong. Even if our assumption is that people will use a containing view. The attempt to lock down thenProceed
in general was probably a little misguided. It certainly came from a good place, we didn't want to pollute a global namespace. However, it came at too steep a cost of maintenance, which is why it's already extended on so many things.
This came from a real-world situation, as I tend to build with this library frequently. The idea was that a had a view, not ContentView
but merely a portion of it, called HomeView
. I wanted to have my preview reflect various places that HomeView
could go. I really didn't want to open a simulator to test out animations between HomeView and Workflow
dictated. This is where I ran into, what at the time, seemed like a silly limitation. PreviewProvider
requires a static method, whereas thenProceed
is an instance method on View
, App
, and Scene
.
I wanted to pontificate on the purpose of preview providers. These aren't just about "show me my view" these are about "show me my view in
The standard SwiftUI examples are a little frustrating to me because they're inconsistent in their interpretation of responsibility. For example, a NavigationView
example usually shows that an enclosing view declares a navigationTitle
. It basically says "If I'm in a nav stack I should look like this". Whereas TabView
examples are the opposite. They almost always have enclosing views ignorant of context and in the TabView
declaration they add .tabItem
contextually to views.
Regardless, if I want to see not a View
containing a WorkflowLauncher
but a FlowRepresentable
in isolation as I develop I might wrap it in my preview provider so that it most accurately represents how it'll render elsewhere. This seems reasonable and logical, therefore is a thing we should support.
Hopefully that serves to clarify motivation and clear up confusion, even if it was long.
I think the part about showing a view in context and also showing a view in multiple states makes sense to me. I've only used previews to visual the design of things as well as show views within other views. The views within other views sounds like what you're talking about here, albeit with views inside of workflows so I think this is a reasonable ask.
I don't normally mind using the simulator or clicking the play button on the canvas, but I could imagine that being heavier in some cases.
It sounds like making thenProceed
static is likely the way to go, but there might be a fancier way to achieve that as well.
It sounds like making thenProceed static is likely the way to go, but there might be a fancier way to achieve that as well.
We thought about that, but the PR actually just made it global. The issue was one of maintenance. This is then Nth thing that came up, there will certainly be an N+1 thing in the future. Rather than continually trying to keep up with Apple and lock it down, it felt better to just open it up.
Is your feature request related to a problem? Please describe.
I want to use previews to view my
FlowRepresentable
as it'll appear in a workflow, even if that's just a single item workflow. However, right nowthenProceed
is not available.Describe the solution you'd like
Either make
thenProceed
globally available so we quit having one-off "I need it added" or add it toPreviewProvider
.Describe alternatives you've considered
I could write my own extension for this, but it should just work out of the box. Additionally, I suppose we could wrap
thenProceed
in some new protocol? However, I don't like the idea that I have to conform to a protocol just to define a workflow. There may be something to investigating resultBuilders in a future version of Swift where they allow those scoped functions. I've seen proposals about it, but for now I don't think we should go that route.