turbolinks / turbolinks-ios

Native iOS adapter for building hybrid apps with Turbolinks 5
MIT License
881 stars 92 forks source link

Visiting the same vistable twice causes weird hang. #127

Closed joeyschomey closed 6 years ago

joeyschomey commented 6 years ago

I have a app with tabs hooked up to visit a page when the user switches tabs. If he clicks the same tab twice, session.visit is called twice on the same visitable, which causes a weird infinite load hang. I can work around it by not having it call session.visit again, but it seems like it should work.

I just reproduced the same behavior in the demo app by cloning this repository and changing:

ApplicationController.swift line 46 to call session.visit after a short delay (which causes the screen to go blank and the app to hang.

  fileprivate func presentVisitableForSession(_ session: Session, url: URL, action: Action = .Advance) {
        let visitable = DemoViewController(url: url)

        if action == .Advance {
            pushViewController(visitable, animated: true)
        } else if action == .Replace {
            popViewController(animated: false)
            pushViewController(visitable, animated: false)
        }

        session.visit(visitable)

        // new code here:
        DispatchQueue.main.asyncAfter(deadline: .now()+2) {
            session.visit(visitable)
        }
    }
zachwaugh commented 6 years ago

A session.visit() call has to be accompanied by the creation of a new Visitable and the related navigation (push/replace/etc). We might be able to guard against it, but I would say it's user error to call it twice like that for the same visitable. I'm not sure your exact use case, but in this example, you should be calling presentVisitableForSession(session, url: url) instead of session.visit() in that asyncAfter block for the correct behavior, which would be to push another view controller on the stack.

In Basecamp, we guard against attempting to navigate to the current URL again, but that's up to the app to decide.