流程协调器
,根据Krzysztof Zabłocki的文章来实现的,适用于:F+MVC
、F+MVVM
、F+VIPER
[TOC]
使用CocoaPods
pod 'DPFlowCoordinator', '~> 3.0.0'
一般的使用方式是建立FlowCoordinator
子类来处理业务流程,子类需要指定流程成功返回的结果,通过父类的范型来指定(下面例子中的Result
)
import DPFlowCoordinator
class LoginFlow: FlowCoordinator<Result> {
override func start(at baseViewController: UIViewController?, completion: CompletionHandler?) {
super.start(at: baseViewController, completion: completion)
// 在这里处理你的业务流程
}
func doSomething() {
// ⚠️️️️️️⚠️⚠️ 在业务流程完成后,需要调用`complete()`方法,来结束流程,否则`FlowCoordinator`生命周期不会完结,并且内存不会被释放
//
end(with: .skip)
}
}
定义Result
,每个流程可以定义自己的Result
extension LoginFlow {
enum Result {
case skip
case failure(Error)
case success(User)
}
}
实现好了业务流程之后,在ViewController
中调用业务流程
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func needsLoginButtonDidClick(_ sender: Any) {
LoginFlow().start(at: self) { (result) -> (Void) in
switch result {
case .skip:
print("取消登录")
case let .success(userInfo):
print("登录成功:\(String(describing: userInfo))")
case let .failure(error):
print("登录失败\(String(describing: error))")
}
}
}
}
更多细节,请参考工程中的
DPFlowCoordinatorExample
DPFlowCoordinator提供了ObjC的API
自己的业务流程需要继承自**FCFlowCoordinator
**
#import <DPFlowCoordinator/DPFlowCoordinator.h>
@interface SettingPasswordFlow : FCFlowCoordinator
@end
然后重写startAtViewController:completion:
方法,并在这里开始你的业务流程
startAtViewController:completion:
一定要调用**super startAtViewController:completion:
**
@implementation SettingPasswordFlow
- (void)startAtViewController:(UIViewController *)baseViewController
completion:(void (^)(FCFlowCoordinatorResult * _Nonnull))completionHandler {
[super startAtViewController:baseViewController completion:completionHandler];
[self showSettingPasswordPage];
}
@end
在你的业务流程结束或者终止时,需要调用**endWithXXX
**方法来使流程完结,不然流程不能完结会导致内存泄露(
- (void)showSettingPasswordPage {
__weak typeof (self) weakself = self;
SettingPasswordViewController *passwordPage = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"SettingPasswordViewController"];
passwordPage.cancelAction = ^(SettingPasswordViewController * _Nonnull page) {
[page dismissViewControllerAnimated:YES completion:nil];
[weakself endWithCancel];
};
passwordPage.finishAction = ^(SettingPasswordViewController * _Nonnull page) {
[page dismissViewControllerAnimated:YES completion:nil];
[weakself endWithSuccessData:@{@"name": @"张三", @"age": @(18)}];
};
passwordPage.failureAction = ^(SettingPasswordViewController * _Nonnull page, NSError * _Nonnull error) {
[page dismissViewControllerAnimated:YES completion:^{
[weakself endWithFailureError:error];
}];
};
[self.baseViewController presentViewController:passwordPage animated:YES completion:nil];
}
业务流程的调用
[[[SettingPasswordFlow alloc] init] startAtViewController:self completion:^(FCFlowCoordinatorResult * _Nonnull result) {
switch (result.category) {
case FCFlowCoordinatorResultCategoryCancel: {
NSLog(@"%s, 取消", __PRETTY_FUNCTION__);
} break;
case FCFlowCoordinatorResultCategorySuccess: {
NSLog(@"%s, 成功: %@", __PRETTY_FUNCTION__, result.data);
} break;
case FCFlowCoordinatorResultCategoryFailure: {
NSLog(@"%s, 失败: %@", __PRETTY_FUNCTION__, result.error);
[weakself alertMessage:result.error.localizedDescription atPage:weakself];
} break;
}
}];
DPFlowCoordinator is released under the MIT license. See LICENSE for details.