Skip to content
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

removedAfterProceeding on last item in Workflow #19

Closed
Tyler-Keith-Thompson opened this issue May 11, 2021 · 12 comments · Fixed by #33
Closed

removedAfterProceeding on last item in Workflow #19

Tyler-Keith-Thompson opened this issue May 11, 2021 · 12 comments · Fixed by #33
Labels
bug Something isn't working

Comments

@Tyler-Keith-Thompson
Copy link
Collaborator

Tyler-Keith-Thompson commented May 11, 2021

Describe the bug

If you have .removedAfterProceeding as the FlowPersistence on an item in a workflow it does not properly remove that item (UIKit)

To Reproduce

Steps to reproduce the behavior:
Create 3 FlowRepresentables the last of which has a flowPersistence of .removedAfterProceeding
Call proceedInWorkflow() on all items in that flow
Observe after OnFinish is called the final UIViewController is still displayed

Expected behavior

The UIViewController should not be displayed after the onFinish block has executed

Screenshots

NO

@Tyler-Keith-Thompson Tyler-Keith-Thompson added bug Something isn't working good first issue Good for newcomers labels May 11, 2021
@brianlombardo brianlombardo moved this from Backlog to To Do in SwiftCurrent Kanban May 24, 2021
@brianlombardo brianlombardo moved this from To Do to In progress (3) in SwiftCurrent Kanban May 26, 2021
@brianlombardo brianlombardo added the duplicate This issue or pull request already exists label May 26, 2021
@brianlombardo
Copy link
Contributor

this bug appears to be addressed in #25

@morganzellers
Copy link
Contributor

@Tyler-Keith-Thompson We're expecting this was fixed in Release 3.0.5 as part of the fix for Issue #25.

@Tyler-Keith-Thompson
Copy link
Collaborator Author

Tyler-Keith-Thompson commented May 28, 2021

It isn't, here is a test to repro:

func testWorkflowCanDestroyAllItems_AndStillProceedThroughFlow_AndCallOnFinish() {
        class FR1: TestViewController { }
        class FR2: TestViewController { }
        class FR3: TestViewController { }
        let root = UIViewController()
        root.loadForTesting()

        let expectOnFinish = self.expectation(description: "onFinish called")
        root.launchInto(Workflow(FR1.self, flowPersistence: .removedAfterProceeding)
                            .thenProceed(with: FR2.self, flowPersistence: .removedAfterProceeding)
                            .thenProceed(with: FR3.self, flowPersistence: .removedAfterProceeding)) { _ in
            XCTAssertUIViewControllerDisplayed(isInstance: root) // FAILS
            XCTAssertNil(UIApplication.topViewController()?.presentingViewController) // FAILS
            expectOnFinish.fulfill()
        }
        XCTAssertUIViewControllerDisplayed(ofType: FR1.self)
        XCTAssert(UIApplication.topViewController()?.presentingViewController === root)
        (UIApplication.topViewController() as? FR1)?.proceedInWorkflow(nil)
        XCTAssertUIViewControllerDisplayed(ofType: FR2.self)
        XCTAssert(UIApplication.topViewController()?.presentingViewController === root)
        (UIApplication.topViewController() as? FR2)?.proceedInWorkflow(nil)
        XCTAssertUIViewControllerDisplayed(ofType: FR3.self)
        (UIApplication.topViewController() as? FR3)?.proceedInWorkflow(nil)

        wait(for: [expectOnFinish], timeout: 3)
    }

@Richard-Gist Richard-Gist removed the duplicate This issue or pull request already exists label May 28, 2021
@Tyler-Keith-Thompson
Copy link
Collaborator Author

This may be a tad complicated, because it'll involve looking at OrchestrationResponder and potentially adding a new action

@Tyler-Keith-Thompson
Copy link
Collaborator Author

Also when you're fixing this consider adding a test for a nav stack workflow as well.

@Richard-Gist Richard-Gist removed the good first issue Good for newcomers label May 28, 2021
@morganzellers morganzellers self-assigned this May 28, 2021
@Richard-Gist Richard-Gist self-assigned this Jun 1, 2021
@morganzellers
Copy link
Contributor

We have a spike branch for this called WIP_removedAfterProceeding.

Currently heading in the direction that OrchestrationResponder should have the responsibility of calling the onFinish closure at the appropriate time. We're currently doing this using a function on OrchestrationResponder called complete.

We believe the desired API behavior is:

Launching a workflow with a presentationType of navigationStack should behave the same if every screen in workflow is shouldLoad == false and Completing a workflow with all screens as persistence of RemovedAfterProceeding

@Tyler-Keith-Thompson
Copy link
Collaborator Author

Not sure I entirely understand the navigationStack thing but I'll caution you that if your thought process is "is doesn't make sense to ask for a navigation stack where every view should not load" that should be something you should make users of the library be explicit about.

If you decide "in the case of a navigationStack where all views shouldLoad return false I'll behave as though you said removedAfterProceeding" you may be violating one of our tenants of good API practices and baking in some magic. Because the user of the API didn't ask for "removedAfterProceeding". We should avoid that magic wherever possible. That being said I may have drastically misunderstood your comment here.

@Richard-Gist
Copy link
Collaborator

Richard-Gist commented Jun 1, 2021

You did. We're working through some of the situations that arise from cleaning out the last VC in a navigation stack because of the ".removedAfterProceeding" being applied to all views. So the end user experience should be similar to that of a workflow that did not have any views that should load.

Example:

Root -> FR1 (removeAfterProceeding) -> FR2 (removeAfterProceeding) -> COMPLETED STATE
And
Root -> FR1 (shouldLoad False) -> FR2 (shouldLoad False) -> COMPLETED STATE

These completed states should be the same. You should be viewing Root. Hopefully that makes more sense.

@Tyler-Keith-Thompson
Copy link
Collaborator Author

This helped clarify. You aren't behaviorally treating them the same, you're noting that the end state is the same. I totally get that.

@Tyler-Keith-Thompson
Copy link
Collaborator Author

Weird edge case to consider: What if I wanted an empty nav controller there? Example:
Workflow1 says "All my items are removedAfterProceeding", in its onFinish I can call workflow.abandon() if I want that nav controller gone, but I could just as easily launch Workflow2 which WANTS that nav controller there for its items.

If you dismiss the nav controller on behalf of the user you may get a weird animation experience where it dismisses, then they launch the next workflow and a new one presents.

Which option provides greater flexibility?

@Richard-Gist
Copy link
Collaborator

I think it boils down to: We should clean up the UINavigationController that we created.

If a user wants to have a shared navigation controller between chained workflows, the more explicit code would be to create a navigation controller and then launchInto from that controller.

@Tyler-Keith-Thompson
Copy link
Collaborator Author

That makes a lot of sense. The user has the choice to create an empty NavController, then launch from that. The flexibility is UIKit flexibility and completely in their control.

@Richard-Gist Richard-Gist removed their assignment Jun 3, 2021
@morganzellers morganzellers removed their assignment Jun 4, 2021
@Richard-Gist Richard-Gist moved this from In progress (3) to Review (2) in SwiftCurrent Kanban Jun 8, 2021
@morganzellers morganzellers moved this from Review (2) to Ready for Demo in SwiftCurrent Kanban Jun 9, 2021
@Richard-Gist Richard-Gist moved this from Ready for Demo to Done in SwiftCurrent Kanban Jun 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
4 participants