-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Persistence in SwiftUI #120
Comments
Began Working on
From this:
To this:
I reverted this change after realizing that
In addition, the |
This realization made me go look at
After some debugging of this example scenario...:
...I realized that the I updated the function as such:
This got me to a scenario where I was seeing:
Unfortunately, neither proceeding nor backing up from SkippedFlowRep is working - it just stays there. |
For that, I had a suspicion that something along the lines of this block will be needed in the
Adding this block into the
|
This AM I verified this behavior in Xcode 13 & 12.5.1 |
Moved to testing out this example app configuration:
Scenario: FlowRep1 -> SKIP (SkippedFlowRep) -> FlowRep2 -> SKIP (SkippedFlowRep) -> FlowRep1 Proceeding through this scenario works, however backing up from the second SkippedFlowRep incorrectly takes you to a FlowRep1. |
This
Is making me think that second
SkippedFlowRep1 should be:
SkippedFlowRep2 should be:
So if going back from SkippedFlowRep2 takes me to FlowRep1, then that makes me think I need to do some more checks in my |
After learning that After some debugging, I have come to the point that this if-check from
So I've updated the function to look like this:
Because I believe the With this change, I'm seeing the navigation stack function the way we expect, but not the transitions. On a proceed from
|
After some debugging and chipping away at the changes made prior, we got back to the state of
This, with the addition of a dispatch for proceed calls to give them more time to finish:
Got us to a place where we're seeing the navigation stack function correctly AND the flow proceed forward correctly. The big thing to note here is that updating |
We continued to investigate and |
I created another spike branch called My thought is that because PassthroughSubject does not go out to all subscribers, and CurrentValueSubject does not send out all events, that I could leverage model.body changing and simply track all my events myself. That is currently in place and works, SORT OF. The behavior when persisting a skipped screen in the middle of a flow is broken. For example, FR1 -> FR2 (skipped) -> FR3 ends up rendering as FR1 on screen, then briefly FR2, then FR3 briefly, then FR2 again. BUT SUCCESS when you have FR1 as skipped, then the app will properly launch with FR2 in place and FR1 in the stack. So if FR1 works as skipped I then tested out FR2 as well, so the example being: FR1(skip) -> FR2(skip) -> FR3. And when I launched the app, everything was correct and I was looking at FR3 and could navigate backward all the way to FR1. But then 💥 Because if you slow animations in the simulator, you'll see FR1 sliding off the screen, FR2 sliding in, then it behaves the same as if FR2 is skipped in the middle (see above). This leads me to believe that things are only working correctly because everything is set up correctly before the first view is rendered. Once a view has rendered, we seem to be hitting race time issues with navigation links being flipped and views being re-rendered and everything going down the toilet. As part of this avoidance of re-rendering, I've tried to capture the state that changes in a StateObject to allow the state to persist WITHOUT also causing another rendering pass, but that hasn't worked so far. And so the investigation continues. |
I created a branch called So the short version:
The ReplaySubject is influenced, but not copied verbatim, by what we read on Medium but changed to suit our specific use-cases. It doesn't have a buffer it just replays all values. |
I think the way forward here is to figure out why do we wiggle back and forth in the animation. To do this, I'm starting to venture into recreating SwiftCurrent piece by piece with dumb logic to figure out what causes the behavior. So far all our investigations have led to a better understanding of SwiftUI and Ultimately we have to figure out why our navigation links |
Just capturing some thoughts on:
👋 Have a good weekend! |
This issue is being removed from our board at this time. We tried to resolve it but the efforts you see above led to incorrect behavior in NavigationLinks and Modals. We have not found a suitable solution that works for iOS 15. The community is welcome to implement this feature, and if we have not documented enough, let us know and we will get you caught up. The main gotchas occur when you have 4 FlowRepresentables and you skip the first 3 with We have also decided that if we can get this to work with iOS 15, that will be enough. We do not need |
Is your feature request related to a problem? Please describe.
In UIKit
flowPersistence
is a deliberately supported feature. in SwiftUI right nowremovedAfterProceeding
is supported (partially by accident) andpersistWhenSkipped
really isn't. I'd like to see support for those, if possible.Describe the solution you'd like
For default presentation:
removedAfterProceeding
means the@State
variable holding onto the view is cleared, this is mostly useful for animations.persistWhenSkipped
I do not believe has any real meaning here, if it's skipped with our default presentation mode then there's really nothing to persist.For navigation links:
removedAfterProceeding
in a perfect world this (somehow) animates in the next view then retroactively changes the back-stack to remove the item you just proceeded from. However I think that's impossible because of how animations for Navigation Views and back stack management work in SwiftUI. So I'm fine with the new view merely replacing the one that gets removed after proceeding.persistWhenSkipped
means that a skipped item is in the backstack. You can navigate backward to it, but when you navigate forward from the previous item it's not animated in. (Again, realizing that animations may be very hard to control here)For modals:
removedAfterProceeding
in a perfect world this (somehow) animates in the next view then retroactively changes the back-stack to remove the item you just proceeded from. However I think that's impossible because of back stack management work in SwiftUI. So I'm fine with the new view merely replacing the one that gets removed after proceeding.persistWhenSkipped
means that a skipped item is in the backstack. You can dismiss backward to it, but when you navigate forward from the previous item it's not animated in. (Again, realizing that animations may be very hard to control here)Describe alternatives you've considered
Expressly have an error (ideally compile time) that stops users from being able to apply persistences that do not work.
The text was updated successfully, but these errors were encountered: