Skip to content

Commit

Permalink
[master] - BUG FIX: when views were hidden initially the proceedInWor…
Browse files Browse the repository at this point in the history
…kflow callback was not being set up correctly, now it is - TT
  • Loading branch information
Tyler-Keith-Thompson committed May 20, 2020
1 parent c82e6ed commit 440c000
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 14 deletions.
44 changes: 30 additions & 14 deletions Workflow/Workflow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ public class Workflow: LinkedList<FlowRepresentableMetaData> {
flowRepresentable.workflow = self
let shouldLoad = flowRepresentable.erasedShouldLoad(with: args)
defer {
let position = node.position
if (shouldLoad) {
let position = node.position
instances.replace(atIndex: position, withItem: flowRepresentable)
firstLoadedInstance = instances.first?.traverse(position)
if let firstLoadedInstance = firstLoadedInstance {
Expand All @@ -133,13 +133,14 @@ public class Workflow: LinkedList<FlowRepresentableMetaData> {
onFinish: onFinish)
}
} else if (!shouldLoad && metadata.staysInViewStack(args) == .hiddenInitially) {
rootView = flowRepresentable
self.presenter?.launch(view: flowRepresentable,
from: from,
withLaunchStyle: metadata.presentationType, metadata: metadata,
animated: false,
completion: nil)

var reference:((Any?) -> Void)?
self.handleCallbackWhenHiddenInitially(viewToPresent: &rootView,
hold: &reference,
instance: flowRepresentable,
instancePosition: position,
from: from,
metadata: metadata,
onFinish: onFinish)
}

}
Expand Down Expand Up @@ -188,7 +189,7 @@ public class Workflow: LinkedList<FlowRepresentableMetaData> {
instance.proceedInWorkflow = $0.value?.proceedInWorkflow
instance.workflow = self

let hold = instance.proceedInWorkflow
var hold = instance.proceedInWorkflow
defer {
instance.proceedInWorkflow = hold
self.replaceInstance(atIndex: index, withInstance: instance)
Expand All @@ -198,11 +199,13 @@ public class Workflow: LinkedList<FlowRepresentableMetaData> {

let shouldLoad = instance.erasedShouldLoad(with: argsToPass) == true
if (!shouldLoad && metadata.staysInViewStack(argsToPass) == .hiddenInitially) {
viewToPresent = instance
self.presenter?.launch(view: instance,
from: self.instances.first?.traverse(node.position)?.value,
withLaunchStyle: metadata.presentationType, metadata: metadata, animated: false, completion: nil)

self.handleCallbackWhenHiddenInitially(viewToPresent: &viewToPresent,
hold: &hold,
instance: instance,
instancePosition: index,
from: self.instances.first?.traverse(node.position)?.value,
metadata: metadata,
onFinish: onFinish)
}

return shouldLoad
Expand Down Expand Up @@ -230,6 +233,19 @@ public class Workflow: LinkedList<FlowRepresentableMetaData> {
}
}
}

private func handleCallbackWhenHiddenInitially(viewToPresent:inout Any?, hold:inout ((Any?) -> Void)?, instance:AnyFlowRepresentable, instancePosition:Int, from:Any?, metadata: FlowRepresentableMetaData, onFinish:((Any?) -> Void)?) {
viewToPresent = instance
self.replaceInstance(atIndex: instancePosition, withInstance: instance)
if let instanceNode = self.instances.first?.traverse(instancePosition) {
self.setupCallbacks(for: instanceNode, onFinish: onFinish)
hold = instanceNode.value?.proceedInWorkflow
}
self.presenter?.launch(view: instance,
from: from,
withLaunchStyle: metadata.presentationType, metadata: metadata, animated: false, completion: nil)

}
}

public class FlowRepresentableMetaData {
Expand Down
57 changes: 57 additions & 0 deletions WorkflowTests/UIKitPresenter/UIKitPresenterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,34 @@ class UIKitPresenterTests: XCTestCase {
XCTAssert(UIApplication.topViewController() is FR2)
}

func testNavWorkflowWhichSkipsAScreen_ButKeepsItInTheViewStack_BacksUp_ThenGoesForwardAgain() {
class FR1: TestViewController { }
class FR2: UIWorkflowItem<Never>, FlowRepresentable {
static func instance() -> AnyFlowRepresentable { FR2() }
func shouldLoad() -> Bool { false }
}
class FR3: TestViewController { }

let nav = UINavigationController()
loadView(controller: nav)

nav.launchInto(Workflow()
.thenPresent(FR1.self)
.thenPresent(FR2.self, staysInViewStack: .hiddenInitially)
.thenPresent(FR3.self), withLaunchStyle: .navigationStack)
waitUntil(UIApplication.topViewController() is FR1)
XCTAssert(UIApplication.topViewController() is FR1)
(UIApplication.topViewController() as? FR1)?.proceedInWorkflow()
waitUntil(UIApplication.topViewController() is FR3)
XCTAssert(UIApplication.topViewController() is FR3)
(UIApplication.topViewController()?.navigationController)?.popViewController(animated: false)
waitUntil(UIApplication.topViewController() is FR2)
XCTAssert(UIApplication.topViewController() is FR2)
(UIApplication.topViewController() as? FR2)?.proceedInWorkflow()
waitUntil(UIApplication.topViewController() is FR3)
XCTAssert(UIApplication.topViewController() is FR3)
}

func testNavWorkflowWhichSkipsFirstScreen_ButKeepsItInTheViewStack() {
class FR1: TestViewController {
override func shouldLoad(with args: Any?) -> Bool {
Expand All @@ -600,6 +628,35 @@ class UIKitPresenterTests: XCTestCase {
XCTAssert(UIApplication.topViewController() is FR1)
}

func testNavWorkflowWhichSkipsFirstScreen_ButKeepsItInTheViewStack_BacksUp_ThenGoesForwardAgain() {
class FR1: TestViewController {
override func shouldLoad(with args: Any?) -> Bool {
_ = super.shouldLoad(with: args)
return false
}
}
class FR2: UIWorkflowItem<Never>, FlowRepresentable {
static func instance() -> AnyFlowRepresentable { FR2() }
}
class FR3: TestViewController { }

let nav = UINavigationController()
loadView(controller: nav)

nav.launchInto(Workflow()
.thenPresent(FR1.self, staysInViewStack: .hiddenInitially)
.thenPresent(FR2.self)
.thenPresent(FR3.self), withLaunchStyle: .navigationStack)
waitUntil(UIApplication.topViewController() is FR2)
XCTAssert(UIApplication.topViewController() is FR2)
(UIApplication.topViewController()?.navigationController)?.popViewController(animated: false)
waitUntil(UIApplication.topViewController() is FR1)
XCTAssert(UIApplication.topViewController() is FR1)
(UIApplication.topViewController() as? FR1)?.proceedInWorkflow()
waitUntil(UIApplication.topViewController() is FR2)
XCTAssert(UIApplication.topViewController() is FR2)
}

func testNavWorkflowWhichDoesNotSkipAScreen_ButRemovesItFromTheViewStack() {
class FR1: TestViewController { }
class FR2: UIWorkflowItem<Never>, FlowRepresentable {
Expand Down

0 comments on commit 440c000

Please sign in to comment.