FlowState 1.5.0

FlowState 1.5.0

Brandon 维护。



FlowState 1.5.0

  • 作者:
  • buba447

FlowState

VersionLicensePlatform

FlowState 是一个轻量级的框架,用于创建 Swift 风格的可组合 Flow Coordinators。FlowState 采用了更函数式的方法来处理 ViewController/Coordinator 模式。您可以将它视为对 Promise 模式的扩展。

FlowState 提供了一组灵活易用的机制,可以

  • 从 View Controllers 中移除所有业务逻辑
  • 执行异步请求
  • 将数据加载到 View Controllers 中,无需管道引用
  • 帮助去除状态性
  • 使 A/B 测试变得简单
  • 创建可组合、可重新排列的流程
  • 分割网络/建模/视图逻辑

它是如何工作的?

FlowState 有两个基本的构建块,它们相辅相成。即 FlowStepFlowStepHandler。您可以将 FlowStep 视为一个承诺和一个任务工厂。 FlowStepHandler 允许 FlowStep 完成,并管理信息路由。

一个 Flow 由一系列 FlowStep 对象组成。它们在链式列表堆栈中链接在一起。第一步开始,一旦这一步由其 FlowStepHandler 完成,第二步就开始,以此类推。

FlowStep 可以管理 View Controller、网络请求或嵌套的 Flow。

FlowStepFlowStepHandler 都是泛型类,它们有两个泛型类型:ContentResultContent 可以被视为步骤的输入。 Content 会自动从步骤路由到其 FlowStepHandler,这使得管理数据流变得容易。 Result 可以被视为步骤的输出,这是步骤在继续之前试图收集的信息。当步骤提供其 Result 时,步骤完成。

流程步骤

让我们看看这个例子。

Example

此示例显示流程中单个步骤的生命周期。协调器启动了一个流程步骤。步骤的意图块分配了一个要显示在屏幕上的ViewControllerViewController拥有一个流程步骤处理器,该处理器在意图块中返回给流程步骤

当用户选择一个选项时,ViewController调用其流程步骤处理器上的complete(option)。然后处理器自动转发完成调用,步骤完成,并将结果路由回协调器。协调器可以处理这些结果,并使用start()启动下一步。

这在代码中是什么样的?

示例

让我们创建一个简单的流程,用于从用户个人资料收集一些信息。

首先,让我们显示我们拥有的信息,显示用户个人资料。

流程步骤有两个主要部分,内容,它定义了步骤显示的内容,以及

结果,它定义了步骤收集的信息。有些步骤不收集信息,

而是交互。

此第一个步骤将显示用户个人资料视图控制器。用户个人资料视图控制器显示

用户个人资料结构体提供的信息。个人资料视图控制器希望在显示时刷新其内容

通过执行网络调用下载个人资料数据。此外,

个人资料视图控制器有一个按钮,允许用户更新他们的名字。

然后,个人资料视图控制器有两个结果操作,下载和updateName,每个都定义在

一个名为用户个人资料操作的枚举中。

个人资料视图控制器还有一个它拥有的流程步骤处理器,称为results

个人资料视图控制器使用results获取其内容,并根据用户的任何交互向意图通知。

/// Create a FlowStep that displays the profile view controller.

let displayStep = FlowStep(UserProfile.self, UserProfileAction.self, identifier: "Profile", { (step) in

/// This block is called each time the step begins.

/// Make a new Profile Display VC

let vc = UserProfileViewController()

/// Set the vc on the navigation controller step.

navigationController.setViewControllers([vc], animated: false)

/// Return the View Controller's FlowStepHandler `results`.

return vc.results

})

显示步骤有两个结果,一个将显示一个编辑用户名的视图控制器,

另一个将下载新的个人资料。

让我们创建一个用于下载新个人资料的步骤。此步骤没有内容,但结果是一个新的

用户个人资料对象。

/// Create a step that downloads the user profile from the internet

let networkStep = FlowStep(Any.self, UserProfile.self, identifier: "User Profile Network", { (step) in



/// Show a loader View Controller

let loader = LoadingModalViewController()

navigationController.present(loader, animated: true, completion: nil)



/// Create step results for this step.

let stepResults = FlowStepHandler(Any.self, UserProfile.self)

/// Make an async network call.

UserProfile.getUser() { (newProfile) in

/// After the download has completed, call completion with the results.

stepResults.complete(newProfile)

}

return stepResults

}) { [unowned displayStep] (step, newProfile) in

if let newProfile = newProfile {

/// Set the new profilew on the display step, which automatically updates it's view controller.

displayStep.content = newProfile

}

/// Dismiss the loading modal.

navigationController.dismiss(animated: true, completion: nil)

}

现在让我们创建一个允许用户编辑其名字的步骤。

编辑名字视图控制器的内容类型为String,结果类型为一个新

let editNameStep = FlowStep(String.self, String.self, identifier: "Edit Name", { (step) in

let vc = StringEntryViewController()

navigationController.pushViewController(vc, animated: true)

return vc.results

})

String

/// Create a step that updates the user profile

let updateNameStep = FlowStep(String.self, UserProfile.self, identifier: "Update Profile Step", { (step) in



/// Show a loader View Controller

let loader = LoadingModalViewController()

navigationController.present(loader, animated: true, completion: nil)



/// Create step results for this step.

let stepResults = FlowStepHandler(Any.self, UserProfile.self)

/// Make an async network call that updates the user profile with the step's content.

UserProfile.updateName(step.content) { (newProfile) in

/// After the download has completed, call completion with the results.

stepResults.complete(newProfile)

}



return stepResults

}) { [unowned displayStep] (step, newProfile) in

if let newProfile = newProfile {

/// Set the new profilew on the display step, which automatically updates it's view controller.

displayStep.content = newProfile

}

/// Dismiss the loading modal.

navigationController.dismiss(animated: true, completion: nil)

/// Optionally you could pop the nav controller here to go back to the profile.

}

接下来,让我们创建一个网络调用,更新用户名并返回更新的用户个人资料

现在让我们将editNameStep链接到updateNameStep

首先,我们需要在editNameStep中添加一个完成闭包,将其结果转发到updateNameStep

editNameStep.setCompletion { (step, newName) in

guard let newName = newName else {

step.nextStep = nil

return

}

/// Forward the results of this step to the updateNameStep

updateNameStep.content = newName

step.nextStep = updateNameStep

}

然后我们将editNameStep的下一步设置为updateNameStep

/// Set the display step completion block to switch between its results

displayStep.setCompletion { (step, action) in

guard let action = action else { return }

switch action {

case .editProfile:

/// Edit profile was pressed.

editTextStep.content = step.content

step.nextStep = editTextStep

case .downloadProfile:

/// Download profile was pressed.

step.nextStep = fakeNetworkStep

}

}

最后,现在我们已经创建了所有步骤,让我们在管理UserProfileView的步骤上设置分叉逻辑。

示例项目

还需要更多吗?

要运行示例项目,请首先克隆仓库,然后从示例目录中执行 pod install

需求

安装

FlowState可通过CocoaPods获得。要安装它,只需将以下行添加到您的Podfile中

将它

pod 'FlowState'

作者

buba447, [email protected]

许可证

FlowState在MIT许可证下提供。更多信息请参阅LICENSE文件。