josshad/signaling
In projects with Rx/Combine there may be a common pattern of sending events/actions to parent view models or coordinators.
RxSwift
import RxSignaling
final class ViewModel {
enum Action {
case showAlert
}
@Signaling<Action> var actions
func doSmth() {
_actions.accept(.showAlert)
}
}
final class Parent {
private let viewModel = ViewModel()
private let disposeBag = DisposeBag()
init() {
viewModel.$actions
.emit(onNext: {
switch $0 {
..
}
})
.disposed(by: disposeBag)
}
}Combine
import CombineSignaling
final class ViewModel {
enum Action {
case showAlert
}
@Signaling<Action> var actions
func doSmth() {
_actions.send(.showAlert)
}
}
final class Parent {
private let viewModel = ViewModel()
private let cancallables = Set<AnyCancellable>()
init() {
viewModel.$actions
.sink(receiveValue: {
switch $0 {
..
}
})
.store(in: cancellables)
}
}Pros:
- the code becomes more compact
- we use common approach to subscribing to
$<variable>as with@Publisherproperty wrapper - you can't modify or emit event from outside of ViewModel
- you can't change property (as you still can do with
lazy varin the first approach)
Installation
RxSwift
...
dependencies: [
.package(url: "https://github.com/josshad/Signaling.git", .upToNextMajor(from: "1.0.0"))
],
targets: [
.target(
name: "...",
dependencies: [
.product(name: "RxSignaling", package: "signaling")
]
),
]Combine
...
dependencies: [
.package(url: "https://github.com/josshad/Signaling.git", .upToNextMajor(from: "1.0.0"))
],
targets: [
.target(
name: "...",
dependencies: [
.product(name: "CombineSignaling", package: "signaling")
]
),
]Package Metadata
Repository: josshad/signaling
Default branch: main
README: README.md