Coordinator destroy

FFIB 6 years ago
parent
commit
d81a35b897

+ 4 - 0
PaiAi/Paiai.xcodeproj/project.pbxproj

@@ -250,6 +250,7 @@
250 250
 		05D269EE227EE0EB0030062C /* GroupItemsOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D269ED227EE0EB0030062C /* GroupItemsOperator.swift */; };
251 251
 		05D269F0227EE0FC0030062C /* PhotoItemsOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D269EF227EE0FC0030062C /* PhotoItemsOperator.swift */; };
252 252
 		05D269F6227EE7F40030062C /* ItemOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D269F5227EE7F40030062C /* ItemOperator.swift */; };
253
+		05D26A01228031F10030062C /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D26A00228031F10030062C /* UIViewController+Rx.swift */; };
253 254
 		05D3A3C621FF010900A29A20 /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D3A3C521FF010900A29A20 /* WebViewController.swift */; };
254 255
 		05D3A3CD22000C3A00A29A20 /* GroupCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D3A3CC22000C3900A29A20 /* GroupCoordinator.swift */; };
255 256
 		05D3A3D02200288400A29A20 /* Storyboarded.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05D3A3CF2200288400A29A20 /* Storyboarded.swift */; };
@@ -510,6 +511,7 @@
510 511
 		05D269ED227EE0EB0030062C /* GroupItemsOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupItemsOperator.swift; sourceTree = "<group>"; };
511 512
 		05D269EF227EE0FC0030062C /* PhotoItemsOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoItemsOperator.swift; sourceTree = "<group>"; };
512 513
 		05D269F5227EE7F40030062C /* ItemOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemOperator.swift; sourceTree = "<group>"; };
514
+		05D26A00228031F10030062C /* UIViewController+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Rx.swift"; sourceTree = "<group>"; };
513 515
 		05D3A3C521FF010900A29A20 /* WebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = "<group>"; };
514 516
 		05D3A3CC22000C3900A29A20 /* GroupCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupCoordinator.swift; sourceTree = "<group>"; };
515 517
 		05D3A3CF2200288400A29A20 /* Storyboarded.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storyboarded.swift; sourceTree = "<group>"; };
@@ -869,6 +871,7 @@
869 871
 			isa = PBXGroup;
870 872
 			children = (
871 873
 				0543276621C68C3300C6388D /* UIImageView+Kingfisher.swift */,
874
+				05D26A00228031F10030062C /* UIViewController+Rx.swift */,
872 875
 			);
873 876
 			path = Extension;
874 877
 			sourceTree = "<group>";
@@ -1796,6 +1799,7 @@
1796 1799
 				05130FE221CA1B04004EF1BE /* GroupNameModificationViewController.swift in Sources */,
1797 1800
 				055EFAD7221A4DB400450AD5 /* GroupQRView.swift in Sources */,
1798 1801
 				05130FE421CA1B04004EF1BE /* MessageCommentAndThumbupCell.swift in Sources */,
1802
+				05D26A01228031F10030062C /* UIViewController+Rx.swift in Sources */,
1799 1803
 				05D3A3CD22000C3A00A29A20 /* GroupCoordinator.swift in Sources */,
1800 1804
 				05130FE521CA1B04004EF1BE /* MessageSystemCell.swift in Sources */,
1801 1805
 				05130FE621CA1B04004EF1BE /* MessageCoordinator.swift in Sources */,

BIN
PaiAi/Paiai.xcodeproj/project.xcworkspace/xcuserdata/FFIB.xcuserdatad/UserInterfaceState.xcuserstate


+ 0 - 5
PaiAi/PaiaiDataKit/PresentLayer/Group/GroupDetail/GroupDetailViewModel.swift

@@ -24,7 +24,6 @@ public class GroupDetailViewModel {
24 24
     
25 25
     public weak var delegate: GroupDetailViewModelDelegate?
26 26
     
27
-    public let didCancel = PublishSubject<Void>()
28 27
     public let didQuit = PublishSubject<Void>()
29 28
     public let item: BehaviorRelay<GroupDetailItem>
30 29
     
@@ -115,10 +114,6 @@ public class GroupDetailViewModel {
115 114
                 self.delegate?.navigationBackToGroupDetail()
116 115
         }).disposed(by: disposeBag)
117 116
     }
118
-    
119
-    deinit {
120
-        didCancel.onNext(())
121
-    }
122 117
 }
123 118
 
124 119
 public extension GroupDetailViewModel {

+ 0 - 6
PaiAi/PaiaiDataKit/PresentLayer/Mine/MineOrderViewModel.swift

@@ -41,8 +41,6 @@ public class MineOrderViewModel {
41 41
         return _isLoading.asObserver()
42 42
     }
43 43
     
44
-    public var didCancel = PublishSubject<Void>()
45
-    
46 44
     public init() {
47 45
         self.repository = OrderRepository()
48 46
     }
@@ -87,8 +85,4 @@ public class MineOrderViewModel {
87 85
     public func didSelect(_ item: OrderItem) {
88 86
         delegate?.didSelect(item)
89 87
     }
90
-    
91
-    deinit {
92
-        didCancel.onNext(())
93
-    }
94 88
 }

+ 3 - 2
PaiAi/Paiai_iOS/App/AppCoordinator.swift

@@ -18,13 +18,14 @@ public final class AppCoordinator: BaseCoordinator<Void> {
18 18
     
19 19
     private let window: UIWindow
20 20
     var shareUserInfoViewModel = UserInfoViewModel()
21
-    var navigationController: UINavigationController
22 21
     var containerViewController: ContainerViewController
23 22
     
24 23
     public init(window: UIWindow) {
25 24
         self.window = window
26 25
         self.containerViewController = ContainerViewController()
27
-        self.navigationController = NavigationController(rootViewController: containerViewController)
26
+        
27
+        super.init(navigationController: NavigationController(rootViewController: containerViewController),
28
+                   viewController: containerViewController)
28 29
     }
29 30
     
30 31
     override public func start() -> Observable<Void> {

+ 3 - 10
PaiAi/Paiai_iOS/App/Group/GroupCoordinator.swift

@@ -11,10 +11,6 @@ import RxSwift
11 11
 import RxCocoa
12 12
 import PaiaiDataKit
13 13
 
14
-enum GroupCoordinatorResult {
15
-    
16
-}
17
-
18 14
 extension NavigationSource {
19 15
     enum Group {
20 16
         case scan       /// 扫码
@@ -26,24 +22,21 @@ extension NavigationSource {
26 22
 }
27 23
 
28 24
 class GroupCoordinator: BaseCoordinator<Void> {
29
-    
30
-    fileprivate let navigationController: UINavigationController
31
-    
25
+        
32 26
     let groupViewController: GroupViewController
33 27
     let source: NavigationSource.Group
34 28
     
35
-    
36 29
     init(_ viewController: GroupViewController,
37 30
          navigationController: UINavigationController,
38 31
          navigationSource: NavigationSource.Group) {
39 32
         self.groupViewController = viewController
40
-        self.navigationController = navigationController
41 33
         self.source = navigationSource
34
+        super.init(navigationController: navigationController, viewController: viewController)
42 35
     }
43 36
     
44 37
     override func start() -> Observable<Void> {
45 38
         groupViewController.viewModel.delegate = self
46
-        return didCancel.asObservable()
39
+        return didCancel
47 40
     }
48 41
 }
49 42
 

+ 4 - 5
PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetailCoordinator.swift

@@ -16,7 +16,6 @@ enum GroupDetailCoordinatorResult {
16 16
 }
17 17
 
18 18
 class GroupDetailCoordinator: BaseCoordinator<GroupDetailCoordinatorResult> {
19
-    let navigationController: UINavigationController
20 19
     let groupDetailViewController: GroupDetailViewController
21 20
     let source: NavigationSource.Group
22 21
     var coordinatorResult = PublishSubject<GroupDetailCoordinatorResult>()
@@ -26,14 +25,14 @@ class GroupDetailCoordinator: BaseCoordinator<GroupDetailCoordinatorResult> {
26 25
          navigationSource: NavigationSource.Group) {
27 26
         self.source = navigationSource
28 27
         self.groupDetailViewController = viewController
29
-        self.navigationController = navigationController
28
+        
29
+        super.init(navigationController: navigationController, viewController: viewController)
30 30
     }
31 31
     
32 32
     override func start() -> Observable<GroupDetailCoordinatorResult> {
33 33
         groupDetailViewController.viewModel.delegate = self
34
-        
35
-        let cancel = groupDetailViewController.viewModel.didQuit.map { _ in GroupDetailCoordinatorResult.quit }
36
-        let quit = groupDetailViewController.viewModel.didCancel.map { _ in GroupDetailCoordinatorResult.cancel }
34
+        let quit = groupDetailViewController.viewModel.didQuit.map { _ in GroupDetailCoordinatorResult.quit }
35
+        let cancel = didCancel.map { _ in GroupDetailCoordinatorResult.cancel }
37 36
         return Observable.amb([cancel, quit])
38 37
     }
39 38
 }

+ 2 - 2
PaiAi/Paiai_iOS/App/Home/HomeCoordinator.swift

@@ -13,15 +13,15 @@ import PaiaiDataKit
13 13
 class HomeCoordinator: BaseCoordinator<Void> {
14 14
     
15 15
     var homeViewController: HomeViewController
16
-    var navigationController: UINavigationController
17 16
     var shareUserInfoViewModel: UserInfoViewModel
18 17
     
19 18
     init(_ viewController: HomeViewController,
20 19
          navigationController: UINavigationController,
21 20
          userInfoViewModel: UserInfoViewModel) {
22 21
         self.homeViewController = viewController
23
-        self.navigationController = navigationController
24 22
         self.shareUserInfoViewModel = userInfoViewModel
23
+        
24
+        super.init(navigationController: navigationController, viewController: viewController)
25 25
     }
26 26
     
27 27
     @discardableResult

+ 2 - 0
PaiAi/Paiai_iOS/App/Login/LoginCoordinator.swift

@@ -18,6 +18,8 @@ class LoginCoordinator: BaseCoordinator<UserInfo> {
18 18
          rootViewController: UIViewController) {
19 19
         self.rootViewController = rootViewController
20 20
         self.loginViewController = loginViewController
21
+        
22
+        super.init(navigationController: UINavigationController(), viewController: loginViewController)
21 23
     }
22 24
     
23 25
     override func start() -> Observable<UserInfo> {

+ 1 - 3
PaiAi/Paiai_iOS/App/Message/MessageCoordinator.swift

@@ -12,17 +12,15 @@ import PaiaiDataKit
12 12
 
13 13
 class MessageCoordinator: BaseCoordinator<Void> {
14 14
     fileprivate let messageViewController: MessageViewController
15
-    fileprivate let navigationController: UINavigationController
16 15
     
17 16
     init(_ viewController: MessageViewController,
18 17
          navigationController: UINavigationController) {
19 18
         messageViewController = viewController
20
-        self.navigationController = navigationController
19
+        super.init(navigationController: navigationController, viewController: viewController)
21 20
     }
22 21
     
23 22
     override func start() -> Observable<Void> {
24 23
         messageViewController.viewModel.delegate = self
25
-        
26 24
         return Observable.never()
27 25
     }
28 26
 }

+ 0 - 7
PaiAi/Paiai_iOS/App/Mine/MineAboutViewController.swift

@@ -21,8 +21,6 @@ final class MineAboutViewController: UIViewController {
21 21
     
22 22
     private var disposeBag = DisposeBag()
23 23
     
24
-    var didCancel = PublishSubject<Void>()
25
-    
26 24
     // MARK: view function
27 25
     override func viewDidLoad() {
28 26
         super.viewDidLoad()
@@ -33,11 +31,6 @@ final class MineAboutViewController: UIViewController {
33 31
         versionLabel.text = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
34 32
         bindGestures()
35 33
     }
36
-    
37
-    override func viewWillDisappear(_ animated: Bool) {
38
-        super.viewWillDisappear(animated)
39
-        didCancel.onNext(())
40
-    }
41 34
 }
42 35
 
43 36
 fileprivate extension MineAboutViewController {

+ 27 - 26
PaiAi/Paiai_iOS/App/Mine/MineCoordinator.swift

@@ -8,23 +8,25 @@
8 8
 
9 9
 import UIKit
10 10
 import RxSwift
11
+import PaiaiUIKit
11 12
 import PaiaiDataKit
12 13
 
13 14
 class MineCoordinator: BaseCoordinator<Void> {
14 15
     
15 16
     let mineViewController: MineViewController
16
-    fileprivate let navigationController: UINavigationController
17 17
     
18 18
     init(_ viewController: MineViewController,
19 19
          navigationController: UINavigationController) {
20 20
         self.mineViewController = viewController
21
-        self.navigationController = navigationController
21
+        super.init(navigationController: navigationController, viewController: viewController)
22 22
     }
23 23
     
24 24
     override func start() -> Observable<Void> {
25 25
         mineViewController.delegate = self
26 26
         return didCancel
27 27
     }
28
+    
29
+    override func listenDeallocate() {}
28 30
 }
29 31
 
30 32
 extension MineCoordinator: MineViewControllerDelegate {
@@ -40,33 +42,25 @@ extension MineCoordinator: MineViewControllerDelegate {
40 42
     func didSelect(_ item: MineItem) {
41 43
         mineViewController.dismissController()
42 44
         
45
+        let vc: UIViewController
43 46
         switch item {
44 47
         case .group:
45
-            let vc = makeMineGroupViewController()
46
-            vc.viewModel.delegate = self
47
-            navigationController.pushViewController(vc)
48
+            vc = makeMineGroupViewController()
49
+            break
48 50
         case .order:
49
-            let vc = makeMineOrderViewController()
50
-            
51
-            vc.viewModel.didCancel.subscribe { _ in
52
-                self.didCancel.onNext(())
53
-                }.disposed(by: disposeBag)
54
-            navigationController.pushViewController(vc)
51
+            vc = makeMineOrderViewController()
52
+            break
55 53
         case .feedback:
56
-            let vc = makeMineFeedbackViewController()
57
-            
58
-            vc.didCancel.subscribe { _ in
59
-                self.didCancel.onNext(())
60
-                }.disposed(by: disposeBag)
61
-            navigationController.pushViewController(vc)
54
+            vc = makeMineFeedbackViewController()
55
+            break
62 56
         case .about:
63
-            let vc = makeMineAboutViewController()
64
-            
65
-            vc.didCancel.subscribe { _ in
66
-                self.didCancel.onNext(())
67
-                }.disposed(by: disposeBag)
68
-            navigationController.pushViewController(vc)
57
+            vc = makeMineAboutViewController()
58
+            break
69 59
         }
60
+        
61
+        vc.rx.deallocated.subscribe(onNext: { _ in
62
+            self.didCancel.onNext(())
63
+        }).disposed(by: disposeBag)
70 64
     }
71 65
     
72 66
     func loginout() {
@@ -78,9 +72,7 @@ extension MineCoordinator: MineGroupViewModelDelegate {
78 72
         let coordinator = GroupCoordinator(makeGroupViewController(item: item),
79 73
                                            navigationController: navigationController,
80 74
                                            navigationSource: .mineGroup)
81
-        coordinate(to: coordinator).subscribe({[weak self] _ in
82
-            self?.didCancel.onNext(())
83
-        }).disposed(by: disposeBag)
75
+        coordinate(to: coordinator).subscribe().disposed(by: disposeBag)
84 76
         navigationController.pushViewController(coordinator.groupViewController)
85 77
     }
86 78
 }
@@ -95,23 +87,32 @@ fileprivate extension MineCoordinator {
95 87
     func makeMineGroupViewController() -> MineGroupViewController {
96 88
         let vc = MineGroupViewController.instantiate()
97 89
         vc.viewModel = MineGroupViewModel()
90
+        vc.viewModel.delegate = self
91
+        navigationController.pushViewController(vc)
92
+        
98 93
         return vc
99 94
     }
100 95
     
101 96
     func makeMineOrderViewController() -> MineOrderViewController {
102 97
         let vc = MineOrderViewController.instantiate()
103 98
         vc.viewModel = MineOrderViewModel()
99
+        navigationController.pushViewController(vc)
100
+        
104 101
         return vc
105 102
     }
106 103
     
107 104
     func makeMineFeedbackViewController() -> MineFeedbackViewController {
108 105
         let vc = MineFeedbackViewController.instantiate()
109 106
         vc.feedbackAPI = FeedbackRemoteAPI()
107
+        navigationController.pushViewController(vc)
108
+        
110 109
         return vc
111 110
     }
112 111
     
113 112
     func makeMineAboutViewController() -> MineAboutViewController {
114 113
         let vc = MineAboutViewController.instantiate()
114
+        navigationController.pushViewController(vc)
115
+        
115 116
         return vc
116 117
     }
117 118
     

+ 0 - 6
PaiAi/Paiai_iOS/App/Mine/MineFeedbackViewController.swift

@@ -19,7 +19,6 @@ final class MineFeedbackViewController: UIViewController {
19 19
     
20 20
     fileprivate let disposeBag = DisposeBag()
21 21
     var feedbackAPI: FeedbackRemoteAPI!
22
-    var didCancel = PublishSubject<Void>()
23 22
     
24 23
     override func viewDidLoad() {
25 24
         super.viewDidLoad()
@@ -28,11 +27,6 @@ final class MineFeedbackViewController: UIViewController {
28 27
         textView.textContainerInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
29 28
         bindTextViewToSendBtn()
30 29
     }
31
-    
32
-    override func viewWillDisappear(_ animated: Bool) {
33
-        super.viewWillDisappear(animated)
34
-        didCancel.onNext(())
35
-    }
36 30
 }
37 31
 
38 32
 /// storyboard button action

+ 7 - 7
PaiAi/Paiai_iOS/App/PhotoDetail/PhotoDetailCoordinator.swift

@@ -11,22 +11,22 @@ import RxSwift
11 11
 import PaiaiDataKit
12 12
 
13 13
 final class PhotoDetailCoordinator: BaseCoordinator<Void> {
14
-    let navigationController: UINavigationController
15 14
     let photoDetailViewController: PhotoDetailViewController
16 15
     let shareViewModel: PhotoDetailViewModel
17 16
     
18
-    init(_ photoDetailVC: PhotoDetailViewController,
17
+    init(_ viewController: PhotoDetailViewController,
19 18
          nav: UINavigationController,
20 19
          viewModel: PhotoDetailViewModel) {
21
-        photoDetailViewController = photoDetailVC
22
-        shareViewModel = viewModel
23
-        navigationController = nav
24
-        photoDetailViewController.viewModel = viewModel        
20
+        self.photoDetailViewController = viewController
21
+        self.shareViewModel = viewModel
22
+        photoDetailViewController.viewModel = viewModel
23
+        
24
+        super.init(navigationController: nav, viewController: viewController)
25 25
     }
26 26
     
27 27
     override func start() -> Observable<Void> {
28 28
         photoDetailViewController.viewModel.delegate = self
29
-        return .never()
29
+        return didCancel
30 30
     }
31 31
 }
32 32
 

+ 18 - 1
PaiAi/Paiai_iOS/Reusable/BaseCoordinator.swift

@@ -14,11 +14,19 @@ public class BaseCoordinator<ResultType> {
14 14
     typealias CoordinationResult = ResultType
15 15
     
16 16
     let disposeBag = DisposeBag()
17
-    let didCancel = PublishSubject<Void>()
17
+    var didCancel = PublishSubject<Void>()
18
+    var navigationController: UINavigationController
19
+    var viewController: UIViewController
18 20
     
19 21
     private let identifier = UUID()
20 22
     private var childCoordinators = [UUID: Any]()
21 23
     
24
+    init(navigationController: UINavigationController, viewController: UIViewController) {
25
+        self.viewController = viewController
26
+        self.navigationController = navigationController
27
+        listenDeallocate()
28
+    }
29
+    
22 30
     private func store<T>(coordinator: BaseCoordinator<T>) {
23 31
         childCoordinators[coordinator.identifier] = coordinator
24 32
     }
@@ -38,4 +46,13 @@ public class BaseCoordinator<ResultType> {
38 46
     func start() -> Observable<ResultType> {
39 47
         fatalError("Start method should be implemented.")
40 48
     }
49
+    
50
+    func listenDeallocate() {
51
+        navigationController.rx.willShow.subscribe(onNext: {[weak self] (_, _) in
52
+            guard let `self` = self else { return }
53
+            if !self.navigationController.viewControllers.contains(self.viewController) {
54
+                self.didCancel.onNext(())
55
+            }
56
+        }).disposed(by: disposeBag)
57
+    }
41 58
 }

+ 40 - 0
PaiAi/Paiai_iOS/Reusable/Extension/UIViewController+Rx.swift

@@ -0,0 +1,40 @@
1
+//
2
+//  UIViewController+Rx.swift
3
+//  Paiai_iOS
4
+//
5
+//  Created by ffib on 2019/5/6.
6
+//  Copyright © 2019 FFIB. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+import RxCocoa
11
+import RxSwift
12
+
13
+public extension Reactive where Base: UIViewController {
14
+    var viewDidLoad: ControlEvent<Void> {
15
+        let source = self.methodInvoked(#selector(Base.viewDidLoad)).map { _ in }
16
+        return ControlEvent(events: source)
17
+    }
18
+    
19
+    var viewWillAppear: ControlEvent<Bool> {
20
+        let source = self.methodInvoked(#selector(Base.viewWillAppear))
21
+            .map { $0.first as? Bool ?? false }
22
+        return ControlEvent(events: source)
23
+    }
24
+    var viewDidAppear: ControlEvent<Bool> {
25
+        let source = self.methodInvoked(#selector(Base.viewDidAppear))
26
+            .map { $0.first as? Bool ?? false }
27
+        return ControlEvent(events: source)
28
+    }
29
+    
30
+    var viewWillDisappear: ControlEvent<Bool> {
31
+        let source = self.methodInvoked(#selector(Base.viewWillDisappear))
32
+            .map { $0.first as? Bool ?? false }
33
+        return ControlEvent(events: source)
34
+    }
35
+    var viewDidDisappear: ControlEvent<Bool> {
36
+        let source = self.methodInvoked(#selector(Base.viewDidDisappear))
37
+            .map { $0.first as? Bool ?? false }
38
+        return ControlEvent(events: source)
39
+    }
40
+}