9.6 KiB
RxSwift: ReactiveX for Swift
Rx is a generic abstraction of computation expressed through Observable<Element>
interface.
This is a Swift version of Rx.
It tries to port as many concepts from the original version as possible, but some concepts were adapted for more pleasant and performant integration with iOS/macOS environment.
Cross platform documentation can be found on ReactiveX.io.
Like the original Rx, its intention is to enable easy composition of asynchronous operations and event/data streams.
KVO observing, async operations and streams are all unified under abstraction of sequence. This is the reason why Rx is so simple, elegant and powerful.
I came here because I want to ...
... understand
- why use rx?
- the basics, getting started with RxSwift
- traits - what are
Single
,Completable
,Maybe
,Driver
, andControlProperty
... and why do they exist? - testing
- tips and common errors
- debugging
- the math behind Rx
- what are hot and cold observable sequences?
... install
- Integrate RxSwift/RxCocoa with my app. Installation Guide
... hack around
- with the example app. Running Example App
- with operators in playgrounds. Playgrounds
... interact
- All of this is great, but it would be nice to talk with other people using RxSwift and exchange experiences.
Join Slack Channel - Report a problem using the library. Open an Issue With Bug Template
- Request a new feature. Open an Issue With Feature Request Template
- Help out Check out contribution guide
... compare
... understand the structure
RxSwift comprises five separate components depending on eachother in the following way:
┌──────────────┐ ┌──────────────┐
│ RxCocoa ├────▶ RxRelay │
└───────┬──────┘ └──────┬───────┘
│ │
┌───────▼──────────────────▼───────┐
│ RxSwift │
└───────▲──────────────────▲───────┘
│ │
┌───────┴──────┐ ┌──────┴───────┐
│ RxTest │ │ RxBlocking │
└──────────────┘ └──────────────┘
- RxSwift: The core of RxSwift, providing the Rx standard as (mostly) defined by ReactiveX. It has no other dependencies.
- RxCocoa: Provides Cocoa-specific capabilities for general iOS/macOS/watchOS & tvOS app development, such as Binders, Traits, and much more. It depends on both
RxSwift
andRxRelay
. - RxRelay: Provides
PublishRelay
andBehaviorRelay
, two simple wrappers around Subjects. It depends onRxSwift
. - RxTest and RxBlocking: Provides testing capabilities for Rx-based systems. It depends on
RxSwift
.
... find compatible
- libraries from RxSwiftCommunity.
- Pods using RxSwift.
... see the broader vision
- Does this exist for Android? RxJava
- Where is all of this going, what is the future, what about reactive architectures, how do you design entire apps this way? Cycle.js - this is javascript, but RxJS is javascript version of Rx.
Usage
Here's an example | In Action |
---|---|
Define search for GitHub repositories ... | |
let searchResults = searchBar.rx.text.orEmpty .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .distinctUntilChanged() .flatMapLatest { query -> Observable<[Repository]> in if query.isEmpty { return .just([]) } return searchGitHub(query) .catchErrorJustReturn([]) } .observeOn(MainScheduler.instance) |
|
... then bind the results to your tableview | |
searchResults .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, repository: Repository, cell) in cell.textLabel?.text = repository.name cell.detailTextLabel?.text = repository.url } .disposed(by: disposeBag) |
Requirements
- Xcode 10.2
- Swift 5.0
For Xcode 10.1 and below, use RxSwift 4.5.
Installation
Rx doesn't contain any external dependencies.
These are currently the supported options:
Manual
Open Rx.xcworkspace, choose RxExample
and hit run. This method will build everything and run the sample app
CocoaPods
# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
pod 'RxSwift', '~> 5'
pod 'RxCocoa', '~> 5'
end
# RxTest and RxBlocking make the most sense in the context of unit/integration tests
target 'YOUR_TESTING_TARGET' do
pod 'RxBlocking', '~> 5'
pod 'RxTest', '~> 5'
end
Replace YOUR_TARGET_NAME
and then, in the Podfile
directory, type:
$ pod install
Carthage
Officially supported: Carthage 0.33 and up.
Add this to Cartfile
github "ReactiveX/RxSwift" ~> 5.0
$ carthage update
Carthage as a Static Library
Carthage defaults to building RxSwift as a Dynamic Library.
If you wish to build RxSwift as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage:
carthage update RxSwift --platform iOS --no-build
sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj
carthage build RxAlamofire --platform iOS
Swift Package Manager
Create a Package.swift
file.
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "RxTestProject",
dependencies: [
.package(url: "https://github.com/ReactiveX/RxSwift.git", from: "5.0.0")
],
targets: [
.target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"])
]
)
$ swift build
To build or test a module with RxTest dependency, set TEST=1
.
$ TEST=1 swift test
Manually using git submodules
- Add RxSwift as a submodule
$ git submodule add git@github.com:ReactiveX/RxSwift.git
- Drag
Rx.xcodeproj
into Project Navigator - Go to
Project > Targets > Build Phases > Link Binary With Libraries
, click+
and selectRxSwift-[Platform]
andRxCocoa-[Platform]
targets
References
- http://reactivex.io/
- Reactive Extensions GitHub (GitHub)
- RxSwift RayWenderlich.com Book
- Boxue.io RxSwift Online Course (Chinese 🇨🇳)
- Erik Meijer (Wikipedia)
- Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)
- Reactive Programming Overview (Jafar Husain from Netflix)
- Subject/Observer is Dual to Iterator (paper)
- Rx standard sequence operators visualized (visualization tool)
- Haskell