Last active
March 20, 2019 20:24
-
-
Save IanKeen/04393f2f29d9c3e67025d96589fdfb97 to your computer and use it in GitHub Desktop.
RxSwift subject to provide public triggering but private subscription
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
extension Driver { | |
/// Create separate input/output access to the same underlying subject | |
/// | |
/// This allows the subject to be hidden and enforce singular access to input/output | |
/// as well as only exposing input _or_ output if needed. | |
/// | |
/// - Parameters: | |
/// - default: The default value to emit in the case of any errors | |
/// - value: The value to start with | |
public static func create(withDefault default: E? = nil, startingWith value: E) -> (input: AnyObserver<E>, output: Driver<E>) { | |
let (input, output) = create(withDefault: `default`) | |
return (input, output.startWith(value)) | |
} | |
/// Create separate input/output access to the same underlying subject | |
/// | |
/// This allows the subject to be hidden and enforce singular access to input/output | |
/// as well as only exposing input _or_ output if needed. | |
/// | |
/// - Parameter default: The default value to emit in the case of any errors | |
public static func create(withDefault default: E? = nil) -> (input: AnyObserver<E>, output: Driver<E>) { | |
let instance = PublishSubject<E>() | |
return ( | |
AnyObserver(instance), | |
instance.asDriver(onErrorDriveWith: `default`.map(Driver.just) ?? .never()) | |
) | |
} | |
} |
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
class API { | |
func obtainIds() -> Observable<[Int]> { | |
return .just([1,2,3,4]) | |
} | |
} | |
class ViewModel { | |
let update: AnyObserver<Void> | |
let dataUpdated: Driver<[String]> | |
init(api: API) { | |
// | |
// here is where we create the input/output | |
let update = Driver<Void>.create() | |
// | |
// | |
self.update = update.input | |
self.dataUpdated = update.output | |
.flatMap { | |
return api | |
.obtainIds() | |
.asDriver(onErrorJustReturn: []) | |
} | |
.map { $0.flatMap(String.init) } | |
} | |
} | |
// in your view controllers data binding.. | |
let viewModel = ViewModel(api: API()) | |
// perhaps bind to a tableview | |
viewModel.dataUpdated.drive { e in | |
print(e) | |
} | |
// button triggers the input | |
someButton.rx.tap.bind(to: viewModel.update) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment