Created
March 30, 2019 16:16
-
-
Save danielt1263/82eb5333b5da068dfdf330d4011d3edd to your computer and use it in GitHub Desktop.
A simplified RxFlow system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Coordinator.swift | |
// RxFlow | |
// | |
// Created by Daniel Tartaglia on 2/13/19. | |
// Copyright © 2019 Daniel Tartaglia. MIT License. | |
// | |
import Foundation | |
import RxSwift | |
public protocol CoordinatorType { | |
associatedtype Step | |
func navigate(to step: Step) -> [Starter] | |
func asCoordinator() -> Coordinator<Step> | |
} | |
extension CoordinatorType { | |
public func asCoordinator() -> Coordinator<Step> { | |
return Coordinator(self.navigate(to:)) | |
} | |
} | |
public final class Coordinator<Step>: CoordinatorType { | |
private let navigate: (Step) -> [Starter] | |
public init(_ navigator: @escaping (Step) -> [Starter]) { | |
navigate = navigator | |
} | |
public func navigate(to step: Step) -> [Starter] { | |
return navigate(step) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Flow.swift | |
// RxFlow | |
// | |
// Created by Daniel Tartaglia on 2/17/19. MIT License | |
// | |
import Foundation | |
import RxSwift | |
public typealias Starter = () -> Void | |
public func flow<C: CoordinatorType, Step>(coordinator: C, presentable: Presentable, step: Step) -> Starter where C.Step == Step { | |
let stepper = presentable.rxVisible | |
.filter { $0 } | |
.map { _ in step } | |
return flow(coordinator: coordinator.asCoordinator(), presentable: presentable, stepper: stepper) | |
} | |
public func flow<C: CoordinatorType, Step>(coordinator: C, presentable: Presentable, oneStep: Step) -> Starter where C.Step == Step { | |
let stepper = presentable.rxVisible | |
.filter { $0 } | |
.map { _ in oneStep } | |
.take(1) | |
return flow(coordinator: coordinator.asCoordinator(), presentable: presentable, stepper: stepper) | |
} | |
public func flow<C: CoordinatorType, O: ObservableConvertibleType>(coordinator: C, presentable: Presentable, stepper: O) -> Starter where C.Step == O.E { | |
return { | |
let coordinator = coordinator | |
_ = stepper | |
.asObservable() | |
.stallUnless(presentable.rxVisible) | |
.takeUntil(presentable.rxDismissed.asObservable()) | |
.observeOn(MainScheduler.instance) | |
.subscribe(onNext: { step in | |
let results = coordinator.navigate(to: step) | |
for each in results { | |
each() | |
} | |
}) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Presentable.swift | |
// RxFlow | |
// | |
// Created by Daniel Tartaglia on 2/13/19. | |
// Copyright © 2019 Daniel Tartaglia. MIT License. | |
// | |
import UIKit | |
import RxSwift | |
import RxCocoa | |
public protocol Presentable { | |
var rxVisible: Observable<Bool> { get } | |
var rxDismissed: Maybe<Void> { get } | |
} | |
extension UIWindow: Presentable { | |
public var rxVisible: Observable<Bool> { | |
return self.rx.sentMessage(#selector(UIWindow.makeKeyAndVisible)).map { _ in true } | |
} | |
public var rxDismissed: Maybe<Void> { | |
return Maybe.never() | |
} | |
} | |
extension UIViewController: Presentable { | |
public var rxVisible: Observable<Bool> { | |
let viewDidAppear = self.rx.sentMessage(#selector(UIViewController.viewDidAppear)).map { _ in true } | |
let viewWillDisappear = self.rx.sentMessage(#selector(UIViewController.viewWillDisappear)).map { _ in false } | |
return Observable.merge(viewDidAppear, viewWillDisappear).startWith(viewIfLoaded?.window != nil) | |
} | |
public var rxDismissed: Maybe<Void> { | |
return self.rx.deallocating | |
.take(1) | |
.asMaybe() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment