https://github.com/jackstone92/combinerx
Helpful bridging functions between RxSwift and Combine frameworks
https://github.com/jackstone92/combinerx
backpressure bridge buffer combine combine-framework pressure rxswift strategy swift
Last synced: about 1 year ago
JSON representation
Helpful bridging functions between RxSwift and Combine frameworks
- Host: GitHub
- URL: https://github.com/jackstone92/combinerx
- Owner: Jackstone92
- License: mit
- Created: 2020-12-06T04:44:15.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-09-20T14:01:09.000Z (over 1 year ago)
- Last Synced: 2025-04-10T21:44:31.292Z (about 1 year ago)
- Topics: backpressure, bridge, buffer, combine, combine-framework, pressure, rxswift, strategy, swift
- Language: Swift
- Homepage:
- Size: 71.3 KB
- Stars: 6
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CombineRx

[](https://en.wikipedia.org/wiki/MIT_License)
[](https://codecov.io/gh/Jackstone92/CombineRx)
The *CombineRx* library contains a series of functions that help with the interoperability between [RxSwift](https://github.com/ReactiveX/RxSwift) and Apple's [Combine](https://developer.apple.com/documentation/combine) frameworks.
## Interoperability between Combine and RxSwift
### Combine to RxSwift
In order to convert Combine `Publisher`s to RxSwift `Observable`s, you can make use of the `asObservable()` function. This can be done as follows:
```swift
import Combine
import RxSwift
import CombineRx
let myBridgedObservable = Just(0).asObservable()
```
It is also possible to convert Combine `Publisher`s to RxSwift `Infallible`s using `.asInfallible()`.
This can be done as follows:
```swift
import Combine
import RxSwift
import CombineRx
let myBridgedInfallible = Just(0)
.setFailureType(to: Never.self)
.asInfallible() // Works when `Failure` type is `Never`.
let myBridgedInfallible = Just(0)
.setFailureType(to: Error.self)
.asInfallible(onErrorRecover: { error in ... }) // Handle the error
let myBridgedInfallible = Just(0)
.setFailureType(to: Error.self)
.asInfallible(onErrorFallbackTo: Just(42).eraseToAnyPublisher()) // Use a fallback `Publisher`
let myBridgedInfallible = Just(0)
.setFailureType(to: Error.self)
.asInfallible(onErrorJustReturn: 42) // Use a fallback value
```
### RxSwift to Combine
In order to convert RxSwift `Observable`s to Combine `Publisher`s, you can make use of the
`asPublisher(withBufferSize:andBridgeBufferingStrategy:)` function. This can be done as follows:
```swift
import Combine
import RxSwift
import CombineRx
let myBridgedPublisher1 = Observable.just(0).asPublisher(withBufferSize: 1, andBridgeBufferingStrategy: .error)
let myBridgedPublisher2 = Observable.from([0, 1, 2, 3]).asPublisher(withBufferSize: 4, andBridgeBufferingStrategy: .error)
```
It is also possible to convert RxSwift `Infallible`s to Combine `Publisher`s
using `asPublisher(withBufferSize:andBridgeBufferingStrategy:)`.
This can be done as follows:
```swift
import Combine
import RxSwift
import CombineRx
let myBridgedPublisher1 = Infallible.just(0).asPublisher(withBufferSize: 1, andBridgeBufferingStrategy: .dropOldest)
let myBridgedPublisher2 = Infallible.from([0, 1, 2, 3]).asPublisher(withBufferSize: 4, andBridgeBufferingStrategy: .dropOldest)
```
One difference between RxSwift and Combine is that Combine adheres to the mechanism of backpressure in order to ensure that `Publisher`s only produce as many elements that `Subscriber`s have requested. This prevents the case where elements might build up in a `Publisher`s buffer faster than they can be processed downstream by a subscriber as this could lead to out-of-memory errors and degradation in performance due to high system resource consumption. Combine applies this backpressure upstream through a contractual obligation by `Publisher`s to only emit an element when it is requested by `Subscriber`s through `Subscribers.Demand` requests.
RxSwift `Observable`s differ in this regard as they rely on a source with an unbounded rate of production and therefore when bridging to a Combine `Publisher`, we must maintain a buffer or drop elements accordingly in order to satisfy the requirements of downstream subscribers.
This is the reason for the required `withBufferSize` and `andBridgeBufferingStrategy` parameters for `asPublisher(withBufferSize:andBridgeBufferingStrategy:)`. `withBufferSize` is where the buffer size should manually be set (ideally based directly on the number of expected elements in the sequence). `andBridgeBufferingStrategy` is the strategy to employ when the maximum buffer capacity is reached. Keeping in line with native Combine strategies, this can either be `error`, where any buffer overflow is treated as an error, `dropNewest` where the elements already present in the buffer are maintained and any new elements are ignored, or finally `dropOldest` where new elements are added to the buffer and replace older elements that were already present.
Additional information on Combine's use of backpressure can be found [here](https://developer.apple.com/documentation/combine/processing-published-elements-with-subscribers).
## Installation
It is currently possible to install this library using Swift Package Manager. In order to do so, please add the current repository as a package dependency using Xcode or include the following in your `Package.swift` file:
```swift
import PackageDescription
let package = Package(
...
dependencies: [
.package(url: "https://github.com/Jackstone92/CombineRx", .upToNextMajor(from: "2.0.0")),
],
...
targets: [
.target(name: "MyTarget", dependencies: ["CombineRx"]),
]
)
```
## Copywrite and license information
Copyright 2020 © Jack Stone
*CombineRx* is made available under the [MIT License](https://github.com/Jackstone92/CombineRx/blob/main/LICENSE)