我有一个macOS应用程序,我想在其中显示入门步骤的流程(模态视图中的视图)。步骤可以是诸如Approve our ToS
或Install helper tool
之类的步骤,总是跟着Completed
步骤并带有Done
按钮,该按钮确认用户已完成所有步骤。有些步骤可能在以前的应用程序启动时已经完成,并且必须进行过滤,因此我们仅显示未完成步骤的入门。
我的伪代码如下:
Get all steps that are not already fulfilled
Show modal view
for every step {
Show it's view in our modal view
Wait until it's fulfilled (tap button)
}
Show the final Completed step
Once all are fulfilled, dismiss modal view
在这种情况下,我选择使用PromiseKit来设置入职流程。
在排队1步时的外观如下:
有效! 代码如下:
class OnboardingStepViewController: NSViewController {
let (fulfillmentPromise, resolver) = Guarantee<Void>.pending()
}
protocol OnboardingStep {
var viewController: OnboardingStepViewController { get }
var alreadyFulfilled: Guarantee<Bool> { get }
}
视图控制器仅具有一个实现其解析器的按钮。
以及用于排队的方法:
func queueSteps(_ steps: [OnboardingStep]) {
// Use asVoid for when and check results back in steps array instead
// https://github.com/mxcl/PromiseKit/issues/264
let fulfillments = steps.map({ $0.alreadyFulfilled.asVoid() })
when(guarantees: fulfillments).done {
var unfulfilled = steps.filter({ !$0.alreadyFulfilled.value! })
guard !unfulfilled.isEmpty else { return }
unfulfilled.append(OnboardingSteps.Completed())
self.queuedSteps = unfulfilled
self.windowController.showOverlay(view: self.view)
var finished = Guarantee()
for step in unfulfilled {
finished = finished.then { Guarantee() { fulfill in
self.showStep(step)
fulfill(())
}}
finished = finished.then {
return step.viewController.fulfillmentPromise
}
}
finished = finished.done {
self.queuedSteps.removeAll()
self.windowController.dismissOverlay()
}
}
}
上面的代码有效。但是,由于我是PromiseKit的新手,所以我想知道是否有任何方法可以对其进行优化?
似乎应该可以更好地表达这一链条。我没有使用或没有正确使用PromiseKit的任何方面?
我为嵌套感到困扰,尤其是外部when(guarantees: fulfillments).done
用来检查alreadyFulfilled
的所有步骤,因此我可以过滤掉未完成的步骤。有更好的方法吗?
我还发现,释放了导致按钮停止在视图中工作的步骤(及其视图控制器)。通过使用self.queuedSteps = unfulfilled
在Promise链之外保存步骤数组来解决此问题。我不确定这是必需的还是执行不力的结果?