RxCombine
RxCombine copied to clipboard
Bi-directional type bridging between RxSwift and Apple's Combine framework
RxCombine
RxCombine provides bi-directional type bridging between RxSwift and Apple's Combine framework.
Note: This is highly experimental, and basically just a quickly-put-together PoC. I gladly accept PRs, ideas, opinions, or improvements. Thank you ! :)
Basic Examples
Check out the Example App in the ExampleApp folder. Run pod install
before opening the project.
Installation
CocoaPods
Add the following line to your Podfile:
pod 'RxCombine'
Swift Package Manager
Add the following dependency to your Package.swift file:
.package(url: "https://github.com/CombineCommunity/RxCombine.git", from: "1.6.0")
Carthage
Carthage support is offered as a prebuilt binary.
Add the following to your Cartfile:
github "CombineCommunity/RxCombine"
I want to ...
Use RxSwift in my Combine code
RxCombine provides several helpers and conversions to help you bridge your existing RxSwift types to Combine.
Note: If you want to learn more about the parallel operators in Combine from RxSwift, check out my RxSwift to Combine Cheat Sheet (or on GitHub).
-
Observable
(and otherObservableConvertibleType
s) have apublisher
property which returns aAnyPublisher<Element, Swift.Error>
mirroring the underlyingObservable
.
let observable = Observable.just("Hello, Combine!")
observable
.publisher // AnyPublisher<String, Swift.Error>
.sink(receiveValue: { value in ... })
-
Relays
andSubjects
can be converted to their Combine-counterparts using thetoCombine()
method, so you can use them as if they are regular Combine Subjects, and have them connected to your existing subjects.
let relay = BehaviorRelay<Int>(value: 0)
// Use `sink` on RxSwift relay
let combineSubject = relay.toCombine()
combineSubject.sink(receiveValue: { value in ... })
// Use `send(value:)` on RxSwift relay
combineSubject.send(1)
combineSubject.send(2)
combineSubject.send(3)
Use Combine in my RxSwift code
RxCombine provides several helpers and conversions to help you bridge Combine code and types into your existing RxSwift codebase.
-
Publisher
s have aasObservable()
method, providing anObservable<Output>
mirroring the underlyingPublisher
.
// A publisher publishing numbers from 0 to 100.
let publisher = AnyPublisher<Int, Swift.Error> { subscriber in
(0...100).forEach { _ = subscriber.receive($0) }
subscriber.receive(completion: .finished)
}
publisher
.asObservable() // Observable<Int>
.subscribe(onNext: { num in ... })
-
PassthroughSubject
andCurrentValueSubject
both have aasAnyObserver()
method which returns aAnyObserver<Output>
. Binding to it from your RxSwift code pushes the events to the underlying Combine Subject.
// Combine Subject
let subject = PassthroughSubject<Int, Swift.Error>()
// A publisher publishing numbers from 0 to 100.
let publisher = AnyPublisher<Int, Swift.Error> { subscriber in
(0...100).forEach { _ = subscriber.receive($0) }
subscriber.receive(completion: .finished)
}
// Convert a Publisher to an Observable and bind it
// back to a Combine Subject 🤯🤯🤯
publisher.asObservable()
.bind(to: subject)
Observable.of(10, 5, 7, 4, 1, 6)
.subscribe(subject.asAnyObserver())
Future ideas
- ~~Add CI / Tests~~
- ~~Carthage Support~~
- Bridge SwiftUI with RxCocoa/RxSwift
- ~~Partial Backpressure support, perhaps?~~
- ... your ideas? :)
License
MIT, of course ;-) See the LICENSE file.
The Apple logo and the Combine framework are property of Apple Inc.