{"id":32315923,"url":"https://github.com/dancewithpeng/dpflowcoordinator","last_synced_at":"2025-10-23T10:55:01.560Z","repository":{"id":41092884,"uuid":"124639666","full_name":"DancewithPeng/DPFlowCoordinator","owner":"DancewithPeng","description":"流程协调器","archived":false,"fork":false,"pushed_at":"2022-06-28T11:35:43.000Z","size":108,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-23T10:54:37.284Z","etag":null,"topics":["coordinates","coordinator","dpflowcoordinator","dputilities","flow","flowcoordinate","flowcoordinator","ios","swift"],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DancewithPeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-10T09:09:32.000Z","updated_at":"2022-06-28T09:38:23.000Z","dependencies_parsed_at":"2022-07-30T21:08:11.428Z","dependency_job_id":null,"html_url":"https://github.com/DancewithPeng/DPFlowCoordinator","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/DancewithPeng/DPFlowCoordinator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DancewithPeng%2FDPFlowCoordinator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DancewithPeng%2FDPFlowCoordinator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DancewithPeng%2FDPFlowCoordinator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DancewithPeng%2FDPFlowCoordinator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DancewithPeng","download_url":"https://codeload.github.com/DancewithPeng/DPFlowCoordinator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DancewithPeng%2FDPFlowCoordinator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280606612,"owners_count":26359387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coordinates","coordinator","dpflowcoordinator","dputilities","flow","flowcoordinate","flowcoordinator","ios","swift"],"created_at":"2025-10-23T10:54:59.810Z","updated_at":"2025-10-23T10:55:01.552Z","avatar_url":"https://github.com/DancewithPeng.png","language":"Objective-C","readme":"# DPFlowCoordinator\n`流程协调器`，根据[Krzysztof Zabłocki](https://twitter.com/merowing_)的[文章](https://academy.realm.io/cn/posts/krzysztof-zablocki-mDevCamp-ios-architecture-mvvm-mvc-viper/)来实现的，适用于：`F+MVC`、`F+MVVM`、`F+VIPER`\n\n[TOC]\n\n## 安装\n\n使用`CocoaPods`\n```\npod 'DPFlowCoordinator', '~\u003e 3.0.0'\n```\n\n\n\n## Swift使用\n\n一般的使用方式是建立`FlowCoordinator`子类来处理业务流程，子类需要指定流程成功返回的结果，通过父类的范型来指定(下面例子中的`Result`)\n\n```swift\nimport DPFlowCoordinator\n\nclass LoginFlow: FlowCoordinator\u003cResult\u003e {\n\n    override func start(at baseViewController: UIViewController?, completion: CompletionHandler?) {\n        super.start(at: baseViewController, completion: completion)\n\n        // 在这里处理你的业务流程\n    }\n\n    func doSomething() {\n        // ⚠️️️️️️⚠️⚠️ 在业务流程完成后，需要调用`complete()`方法，来结束流程，否则`FlowCoordinator`生命周期不会完结，并且内存不会被释放\n      \t// \n      \tend(with: .skip)\n    }\n}\n```\n\n定义`Result`，每个流程可以定义自己的`Result`\n\n```swift\nextension LoginFlow {\n    \n    enum Result {\n        case skip\n        case failure(Error)\n        case success(User)\n    }\n}\n```\n\n实现好了业务流程之后，在`ViewController`中调用业务流程\n\n```swift\nclass MainViewController: UIViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n    }\n    \n    @IBAction func needsLoginButtonDidClick(_ sender: Any) {\n\n        LoginFlow().start(at: self) { (result) -\u003e (Void) in\n            switch result {\n            case .skip:\n                print(\"取消登录\")\n            case let .success(userInfo):\n                print(\"登录成功:\\(String(describing: userInfo))\")\n            case let .failure(error):\n                print(\"登录失败\\(String(describing: error))\")\n            }\n        }\n    }    \n}\n```\n\n\u003e 更多细节，请参考工程中的`DPFlowCoordinatorExample`\n\n\n\n## ObjC使用\n\n**DPFlowCoordinator**提供了ObjC的API\n\n自己的业务流程需要继承自**`FCFlowCoordinator`**\n\n```objc\n#import \u003cDPFlowCoordinator/DPFlowCoordinator.h\u003e\n\n@interface SettingPasswordFlow : FCFlowCoordinator\n  \n@end\n```\n\n然后重写`startAtViewController:completion:`方法，并在这里开始你的业务流程\n\n⚠️⚠️⚠️ 重写`startAtViewController:completion:`一定要调用**`super startAtViewController:completion:`**\n\n```objc\n@implementation SettingPasswordFlow\n\n- (void)startAtViewController:(UIViewController *)baseViewController\n                   completion:(void (^)(FCFlowCoordinatorResult * _Nonnull))completionHandler {\n    [super startAtViewController:baseViewController completion:completionHandler];\n    \n    [self showSettingPasswordPage];\n}\n\n@end\n```\n\n在你的业务流程结束或者终止时，需要调用**`endWithXXX`**方法来使流程完结，不然流程不能完结会导致内存泄露（⚠️⚠️⚠️）\n\n```objective-c\n- (void)showSettingPasswordPage {\n    \n    __weak typeof (self) weakself = self;\n    \n    SettingPasswordViewController *passwordPage = [[UIStoryboard storyboardWithName:@\"Main\" bundle:nil] instantiateViewControllerWithIdentifier:@\"SettingPasswordViewController\"];\n    passwordPage.cancelAction = ^(SettingPasswordViewController * _Nonnull page) {\n        [page dismissViewControllerAnimated:YES completion:nil];\n        [weakself endWithCancel];\n    };\n    \n    passwordPage.finishAction = ^(SettingPasswordViewController * _Nonnull page) {\n        [page dismissViewControllerAnimated:YES completion:nil];\n        [weakself endWithSuccessData:@{@\"name\": @\"张三\", @\"age\": @(18)}];\n    };\n    \n    passwordPage.failureAction = ^(SettingPasswordViewController * _Nonnull page, NSError * _Nonnull error) {\n        [page dismissViewControllerAnimated:YES completion:^{\n            [weakself endWithFailureError:error];\n        }];\n    };\n    \n    [self.baseViewController presentViewController:passwordPage animated:YES completion:nil];\n}\n```\n\n业务流程的调用\n\n```objc\n[[[SettingPasswordFlow alloc] init] startAtViewController:self completion:^(FCFlowCoordinatorResult * _Nonnull result) {\n    switch (result.category) {\n        case FCFlowCoordinatorResultCategoryCancel: {\n            NSLog(@\"%s, 取消\", __PRETTY_FUNCTION__);\n        } break;\n        case FCFlowCoordinatorResultCategorySuccess: {\n            NSLog(@\"%s, 成功: %@\", __PRETTY_FUNCTION__, result.data);\n        } break;\n        case FCFlowCoordinatorResultCategoryFailure: {\n            NSLog(@\"%s, 失败: %@\", __PRETTY_FUNCTION__, result.error);\n            [weakself alertMessage:result.error.localizedDescription atPage:weakself];\n        } break;\n    }\n}];\n```\n\n\n\n## 参考文档\n\n- [Krzysztof Zabłocki的中文版文章](https://academy.realm.io/cn/posts/krzysztof-zablocki-mDevCamp-ios-architecture-mvvm-mvc-viper/)\n- [Krzysztof Zabłocki的英文版文章](https://academy.realm.io/posts/krzysztof-zablocki-mDevCamp-ios-architecture-mvvm-mvc-viper/)\n\n\n\n## LICENSE \n\nDPFlowCoordinator is released under the MIT license. See [LICENSE](LICENSE) for details.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdancewithpeng%2Fdpflowcoordinator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdancewithpeng%2Fdpflowcoordinator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdancewithpeng%2Fdpflowcoordinator/lists"}