STDevRxExt contains some extension functions for RxSwift and RxCocoa which makes our live easy.

Overview

STDevRxExt

CI Status Platform Cocoapods SPM compatible codecov License

Example

To run the Example.playground, clone the repo, and run pod install from the Example directory first.

Requirements

  • iOS 9.0+
  • tvOS 9.0+
  • macOS 10.10+
  • watchOS 3.0+
  • Swift 5.0+
  • Xcode 11+

Installation

CocoaPods

STDevRxExt is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'STDevRxExt'
Swift Package Manager

You can use The Swift Package Manager to install STDevRxExt by adding the proper description to your Package.swift file:

import PackageDescription

let package = Package(
    name: "YOUR_PROJECT_NAME",
    targets: [],
    dependencies: [
        .package(url: "https://github.com/STDevTM/STDevRxExt.git", from: "1.0.0")
    ]
)

Next, add STDevRxExt to your targets dependencies like so:

.target(
    name: "YOUR_TARGET_NAME",
    dependencies: [
        "STDevRxExt",
    ]
),

Then run swift package update.

List of All Extensions

Filter Extensions

Allow only true elements from Observable<Bool>:

let disposeBag = DisposeBag()

Observable.of(true, false, false, true, true)
    .allowTrue()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

true
true
true

You can use allowTrue on Bool? as well. In this case nil elements will be ignored:

let disposeBag = DisposeBag()

Observable.of(true, false, nil, true, nil, true)
    .allowTrue()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

true
true
true

If you prefer to allow nil elements as well then you can use allowTrueOrNil like this:

let disposeBag = DisposeBag()

Observable.of(true, false, nil, true, nil, true, false)
    .allowTrueOrNil()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

true
true
true
true
true

Map Extensions

You can map every element in sequence with provided value.

let disposeBag = DisposeBag()

Observable.of(1, 5, 7, 8)
    .map(to: "ping")
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

ping
ping
ping
ping

You can map every element in sequence by procided Key Path.

let disposeBag = DisposeBag()

   let observable = Observable.of(
            Book(title: "Twenty Thousand Leagues Under the Sea", author: Author("Jules", "Verne")),
            Book(title: "Hamlet", author: Author("William", "Shakespeare")),
            Book(title: "Hearts of Three", author: Author("Jack", "London"))
        )

    observable
        .map(at: \.title)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)

    observable
        .map(at: \.author.firstName)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)

Output will be:

Twenty Thousand Leagues Under the Sea
Hamlet
Hearts of Three

Jules
William
Jack

Cast Extensions

You can do downcast elements in sequence using cast(to:).

let disposeBag = DisposeBag()

Observable<CustomStringConvertible>.of("1", "5", "7", "8")
    .cast(to: String.self)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

Optional("1")
Optional("5")
Optional("7")
Optional("8")

In order to do force downcast use forceCast(to:) liek this:

let disposeBag = DisposeBag()

Observable<CustomStringConvertible>.of("1", "5", "7", "8")
    .forceCast(to: String.self)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

Output will be:

1
5
7
8

In case of downcast exception it will return Observable.error(RxCastError.castFailed).

Allow extension functions can be used on Driver as well, except forceCast(to:).

Other Extensions

Sometimes we need to update some subject or observer on each next event of Observable or Driver. For example:

request
    .do(onNext: { [weak self] _ in
        self?.inProgress.onNext(true)
    })
    .flatMap {
        service.doRequest($0)
    }
    .do(onNext: { [weak self] _ in
        self?.inProgress.onNext(false)
    })
    .subscribe(onNext: { response in
        dump(response)
    })
    .disposed(by: disposeBag)

You can use update(_:with:) method for shorting code like this:

request
    .update(inProgress, with: true)
    .flatMap {
        service.doRequest($0)
    }
    .update(inProgress, with: false)
    .subscribe(onNext: { response in
        dump(response)
    })
    .disposed(by: disposeBag)

Author

Tigran Hambardzumyan, [email protected]

Support

Feel free to open issues with any suggestions, bug reports, feature requests, questions.

Let us know!

We’d be really happy if you sent us links to your projects where you use our component. Just send an email to [email protected] And do let us know if you have any questions or suggestion.

License

STDevRxExt is available under the MIT license. See the LICENSE file for more info.

You might also like...
iOS & OSX Bluetooth library for RxSwift
iOS & OSX Bluetooth library for RxSwift

RxBluetoothKit is a Bluetooth library that makes interaction with BLE devices much more pleasant. It's backed by RxSwift and CoreBluetooth and it prov

RxSwift reactive wrapper for view gestures
RxSwift reactive wrapper for view gestures

RxGesture Usage To run the example project, clone the repo, in the Example folder open RxGesture.xcworkspace. You might need to run pod install from t

Handy RxSwift extensions on NSObject, including rx.disposeBag.
Handy RxSwift extensions on NSObject, including rx.disposeBag.

NSObject+Rx If you're using RxSwift, you've probably encountered the following code more than a few times. class MyObject: Whatever { let disposeBag

RxSwift extensions for Core Data

RxCoreData Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements Xcode 9.0 Swift 4.0

Support Combine Assign subscriber in RxSwift.

RxAssign Support Combine Assign subscriber in RxSwift. Assign uses a KeyPath which is really nice and useful. ** RxAssign extends Driver and Signal in

This is the demo of MVVM-C structure with dependency injection using RxSwift.
This is the demo of MVVM-C structure with dependency injection using RxSwift.

MVVMC-Demo Demo defination This is the demo project, I have integrated two APIs for MovieDB APIS (https://www.themoviedb.org/). One for the listing of

Dynamic and type-safe framework for building linear and non-linear flows.

FlowKit FlowKit is a dynamic flow framework capable of building a flow, based on conditions and ordered according to a logic of next steps. By using F

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.
Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift. ⚠️ Looking for the Objective-C API? 🎉 Migrating from RAC 4.x? 🚄 Release Road

Simple and lightweight Functional Reactive Coding in Swift for the rest of us
Simple and lightweight Functional Reactive Coding in Swift for the rest of us

The simplest ObservableT implementation for Functional Reactive Programming you will ever find. This library does not use the term FRP (Functional R

Comments
  • Release 1.0.0

    Release 1.0.0

    Adding Swift Package Manager Support Adding tvOS, macOS, watchOS Support Adding Unit Tests Update GitHub action workflows Remove filterIfNil extension Bumped version name to 1.0.0

    opened by hamtiko 0
  • Add emptyIfNil extension for optional arrays

    Add emptyIfNil extension for optional arrays

    For Observable types with Optional Array elements it will be nice to have emptyIfNil extension which will return empty array if the element is nil and will return non-optional Array.

    enhancement 
    opened by tigran-stdev 0
Releases(1.1.0)
Owner
STDev
STDev is a full-stack web and mobile app design and development company founded about 10 years ago.
STDev
Realm RxSwift - This application was written in order to use Realm, RxSwift frameworks in real example

Realm_RxSwift This simple app was written to introduce basic operations of some

Elbek Khasanov 3 Apr 7, 2022
RxAlamoRecord combines the power of the AlamoRecord and RxSwift libraries to create a networking layer that makes interacting with API's easier than ever reactively.

Written in Swift 5 RxAlamoRecord combines the power of the AlamoRecord and RxSwift libraries to create a networking layer that makes interacting with

Dalton Hinterscher 9 Aug 7, 2020
Super Simple Pager with RxSwift extension

SSPager Super Simple Pager Example To run the example project, clone the repo, and run pod install from the SSPagerExample directory first. Installati

9oya 4 Jul 10, 2022
RxSwift extension for RealmSwift's types

RxRealm This library is a thin wrapper around RealmSwift ( Realm Docs ). Table of contents: Observing object collections Observing a single object Wri

RxSwift Community 1.1k Jan 6, 2023
UIKitPreviews - A simple way to see your UIKit ViewController changes live and on-demand

SwiftUI preview provider for UIKit A simple way to see your UIKit ViewController

Emad Beyrami 8 Jan 8, 2023
RxSwift extentions for Swift optionals and "Occupiable" types

RxOptional RxSwift extentions for Swift optionals and "Occupiable" types. Usage All operators are available on Driver as well unless otherwise marked.

Thane Gill 8 Jun 28, 2020
🤖 RxSwift + State Machine, inspired by Redux and Elm.

RxAutomaton RxSwift port of ReactiveAutomaton (State Machine). Terminology Whenever the word "signal" or "(signal) producer" appears (derived from Rea

Yasuhiro Inami 719 Nov 19, 2022
RxSwift bindings for Permissions API in iOS.

RxPermission RxSwift bindings for Permission API that helps you with Permissions in iOS. Installation RxPermission is available through CocoaPods. I c

Luke 230 Dec 27, 2022
RxSwift wrapper around the elegant HTTP networking in Swift Alamofire

RxAlamofire RxAlamofire is a RxSwift wrapper around the elegant HTTP networking in Swift Alamofire. Getting Started Wrapping RxSwift around Alamofire

RxSwift Community 1.6k Jan 3, 2023
A testable RxSwift wrapper around MultipeerConnectivity

A testable RxSwift wrapper around MultipeerConnectivity RxMultipeer is a RxSwift wrapper for MultipeerConnectivity. Using the adapter pattern, we can

RxSwift Community 69 Jul 5, 2022