Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.

Last update: Jun 21, 2022

ReactiveCocoa

Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.

Join the ReactiveSwift Slack community.


Carthage compatible CocoaPods compatible SwiftPM compatible GitHub release Swift 5.1 platforms

⚠️ Looking for the Objective-C API?

🎉 Migrating from RAC 4.x?

🚄 Release Roadmap

What is ReactiveSwift?

ReactiveSwift offers composable, declarative and flexible primitives that are built around the grand concept of streams of values over time. These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation.

For more information about the core primitives, see ReactiveSwift.

What is ReactiveCocoa?

ReactiveCocoa wraps various aspects of Cocoa frameworks with the declarative ReactiveSwift primitives.

  1. UI Bindings

    UI components expose BindingTargets, which accept bindings from any kind of streams of values via the <~ operator.

    // Bind the `name` property of `person` to the text value of an `UILabel`.
    nameLabel.reactive.text <~ person.name

    Note: You'll need to import ReactiveSwift as well to make use of the <~ operator.

  2. Controls and User Interactions

    Interactive UI components expose Signals for control events and updates in the control value upon user interactions.

    A selected set of controls provide a convenience, expressive binding API for Actions.

    // Update `allowsCookies` whenever the toggle is flipped.
    preferences.allowsCookies <~ toggle.reactive.isOnValues
    
    // Compute live character counts from the continuous stream of user initiated
    // changes in the text.
    textField.reactive.continuousTextValues.map { $0.characters.count }
    
    // Trigger `commit` whenever the button is pressed.
    button.reactive.pressed = CocoaAction(viewModel.commit)
  3. Declarative Objective-C Dynamism

    Create signals that are sourced by intercepting Objective-C objects, e.g. method call interception and object deinitialization.

    // Notify after every time `viewWillAppear(_:)` is called.
    let appearing = viewController.reactive.trigger(for: #selector(UIViewController.viewWillAppear(_:)))
    
    // Observe the lifetime of `object`.
    object.reactive.lifetime.ended.observeCompleted(doCleanup)
  4. Expressive, Safe Key Path Observation

    Establish key-value observations in the form of SignalProducers and DynamicPropertys, and enjoy the inherited composability.

    // A producer that sends the current value of `keyPath`, followed by
    // subsequent changes.
    //
    // Terminate the KVO observation if the lifetime of `self` ends.
    let producer = object.reactive.producer(forKeyPath: #keyPath(key))
    	.take(during: self.reactive.lifetime)
    
    // A parameterized property that represents the supplied key path of the
    // wrapped object. It holds a weak reference to the wrapped object.
    let property = DynamicProperty<String>(object: person,
                                           keyPath: #keyPath(person.name))

But there are still more to be discovered and introduced. Read our in-code documentations and release notes to find out more.

Getting started

ReactiveCocoa supports macOS 10.9+, iOS 8.0+, watchOS 2.0+, and tvOS 9.0+.

Carthage

If you use Carthage to manage your dependencies, simply add ReactiveCocoa to your Cartfile:

10.1 ">
github "ReactiveCocoa/ReactiveCocoa" ~> 10.1

If you use Carthage to build your dependencies, make sure you have added ReactiveCocoa.framework and ReactiveSwift.framework to the "Linked Frameworks and Libraries" section of your target, and have included them in your Carthage framework copying build phase.

CocoaPods

If you use CocoaPods to manage your dependencies, simply add ReactiveCocoa to your Podfile:

pod 'ReactiveCocoa', '~> 10.1'

Swift Package Manager

If you use Swift Package Manager, simply add ReactiveCocoa as a dependency of your package in Package.swift:

.package(url: "https://github.com/ReactiveCocoa/ReactiveCocoa.git", branch: "master")

Git submodule

  1. Add the ReactiveCocoa repository as a submodule of your application’s repository.
  2. Run git submodule update --init --recursive from within the ReactiveCocoa folder.
  3. Drag and drop ReactiveCocoa.xcodeproj and Carthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj into your application’s Xcode project or workspace.
  4. On the “General” tab of your application target’s settings, add ReactiveCocoa.framework and ReactiveSwift.framework to the “Embedded Binaries” section.
  5. If your application target does not contain Swift code at all, you should also set the EMBEDDED_CONTENT_CONTAINS_SWIFT build setting to “Yes”.

Have a question?

If you need any help, please visit our GitHub issues or Stack Overflow. Feel free to file an issue if you do not manage to find any solution from the archives.

Release Roadmap

Current Stable Release:
GitHub release

In Development

Plan of Record

ABI stability release

ReactiveCocoa is expected to declare library ABI stability when Swift rolls out resilience support in Swift 5. Until then, ReactiveCocoa will incrementally adopt new language features.

GitHub

https://github.com/ReactiveCocoa/ReactiveCocoa
Comments
  • 1. Request - ReactiveCocoa chat room

    Would like to be able to congregate with others using and learning ReactiveCocoa. Of course I could just join/create the channel on freenode if you guys don't want to do a sort of 'official' room.

    Reviewed by bobspryn at 2013-10-17 20:45
  • 2. Remove property subjects, refactor bindings

    This is a sweeping refactor of the property subject and binding code, to simultaneously solve a few different problems:

    1. Duplicated implementation logic
    2. Confusion about which side bindings go on, how many you need to create to do things, etc.
    3. ~~Confusion about how bindings don't echo values sent to them~~
    4. Complexity from supporting N-way bindings

    Still a huge work-in-progress, but I'd love feedback on the API. In particular, are the separate endpoint properties useful?

    @Coneko @andymatuschak

    Reviewed by jspahrsummers at 2013-07-21 10:13
  • 3. RACDC 2014

    We're gonna host a day of ReactiveCocoa talks and Q&A at the GitHub office during WWDC week this year.

    The current plan is to do it on Tuesday, June 3rd, with a rough agenda like the following (as suggested by @dannygreg):

    • Late(ish) start - ~11am
    • Brief kickoff talk (I'll do a quick overview of the day)
    • 2 or 3 talks (each ~ 30 mins)
    • Lazy Lunch
    • Panel and QA discussion
    • Social/"networking" time

    We'll have a proper event invitation coming soon, to which you can RSVP. However, we'd like to solicit talks from RAC collaborators.

    Would anyone from @ReactiveCocoa/reactivecocoa be interested in speaking?

    Reviewed by jspahrsummers at 2014-05-23 18:04
  • 4. The Great Swiftening (a.k.a. the new 3.0)

    Resolves #1365 and #1366. Per my comments in #1369, this is intended to be a long-running branch that will eventually become RAC 3.0, supplanting the current 3.0-development work.

    To get us started, I basically just subtree merged jspahrsummers/RxSwift into here, then bridged several RAC classes back and forth.

    Reviewed by jspahrsummers at 2014-06-19 06:52
  • 5. Replace ColdSignal and HotSignal with SignalProducer and Signal

    After the long discussion in #1650, I invited @NachoSoto, @andymatuschak, and @kastiglione to talk more in-depth about the Swift APIs, and specifically where they need improvement.

    We had a really, really great brainstorming session, and this is the result. The good news is that we all feel pretty good about this direction, and the bad news is that everything is getting rewritten again. :trollface:

    The important bits are documented on the types themselves, but here’s the handy Quick Start guide of the proposed changes:

    1. HotSignal<T> will be replaced by Signal<T>. Besides the name change, these signals can now send Error and Completed events. This avoids a lot of the lifecycle weirdness that has come up with a value-only HotSignal.
    2. ColdSignal<T> will be replaced by SignalProducer<T>. As the name implies, a signal producer creates Signals (via the start method). You can kind of think of the relationship as something like:
      • SignalProducer : Signal :: RACSignal : subscription
      • SignalProducer : Signal :: class : instance
    3. Most of the basic operators are written in terms of Signal, but can be lifted to apply to SignalProducer instead.
    4. Operators that benefit from “cold” semantics, like retry and repeat, are written in terms of SignalProducer.

    The advantages here are:

    • The relationship between “hot” and “cold” signals is now much more explicit and well-defined. A “cold” signal (a producer) creates “hot” signals, each of which represents a “subscription” (in RAC 2.x terms).
    • Many operators only have to be written once, in terms of Signal, and can be lifted to the SignalProducer level.
    • The semantics and/or difficulties of converting between “hot” and “cold” are more obvious, I think. You don’t need to swap between them on the fly, because they mean different things.
    • Signal lifetime is now consistent, and completely defined by the event stream. Signal producers don’t do anything special—they really are just value types, and don’t encode any information about lifetime.

    I’ll also make some notes in the changes below, to explain more specific things. Please leave feedback if you have it! :bow:

    Reviewed by jspahrsummers at 2014-12-28 21:17
  • 6. RACDC 2015

    Just like last year and the year before, we want to do some kind of RAC community event during WWDC week (June 8–12).

    We don't know what, though, or when. Did you particularly like either of the previous formats, or any aspects of them? Do you have any ideas for something new we should try?

    I'd love to hear your thoughts! :pray:

    /cc @ReactiveCocoa/reactivecocoa

    Reviewed by jspahrsummers at 2015-04-17 21:10
  • 7. Cocoa extensions from Rex.

    Changes

    General

    • [x] Updated for Swift 3.0 GM.
    • [x] A standalone rac_signalForSelector port.
    • [x] ~~Hide the ReactiveCocoaPrivate module.~~
    • [x] Adopted BindingTarget for all non-observable key paths.
    • [x] Update the documentation.

    The Reactive proxy

    • [x] Moved all extension method and properties to Reactive.
    • [x] Point to a new ReactiveSwift (pre-)release with Reactive.

    CocoaAction

    • [x] Consolidated the API of CocoaAction.
    • [x] Parameterized CocoaAction with an assumed sender type.

    Control bindings and values

    • [x] Extensions for NSControl.
    • [x] Text controls now expose an end-of-editing signal by default, with continuous counterparts added.
    • [x] Control values are split into a pair of binding target and signal.
    • [x] UIControl.reactive.trigger(for:) for all UIControlEvents.

    Blocked by:

    • [x] Reactive. https://github.com/ReactiveCocoa/ReactiveSwift/pull/51
    • [x] Scheduler in BindingTarget. https://github.com/ReactiveCocoa/ReactiveSwift/pull/49
    • [x] API Design: Exposing the control values. https://github.com/ReactiveCocoa/ReactiveCocoa/issues/3229
    • [x] API Design: Control Binding API for Actions. https://github.com/ReactiveCocoa/ReactiveCocoa/issues/3233

    Review

    • [x] @mdiep
    • [x] @NachoSoto
    • Others
    Reviewed by andersio at 2016-09-22 11:17
  • 8. How do I cancel the work of inner producers?

    Let's say I have parallel work I want to do, such as downloading multiple images. Each of these downloads is represented by a SignalProducer. I create them and flatten them using the Merge strategy. When I start the outer producer and get a disposable I expected that disposing of that would also dispose of the inner producers. What actually happens is that after disposal, my outer producer stops receiving events, but the actual work being done by the inner producers continues, because they have not been disposed.

    How do I get the actual work being done by the inner producers to stop? Here's some test code that illustrates the scenario:

    func producerOfValues(values: [String]) -> SignalProducer<String, NoError> {
        return SignalProducer<String, NoError> {observer, disposable in
            for value in values {
                sleep(1)
                print("doing work: \(value)")
                sendNext(observer, value)
                if disposable.disposed { // 'disposed' is never true
                    print("producer disposed")
                    break
                }
            }
            sendCompleted(observer)
        }
    }
    
    let (signal, sink) = SignalProducer<SignalProducer<String, NoError>, NoError>.buffer(2)
    let flattened = signal.flatten(.Merge)
    
    let letterProducer = producerOfValues(["a", "b", "c"])
    let numberProducer = producerOfValues(["1", "2", "3"])
    
    sendNext(sink, letterProducer.startOn(QueueScheduler()))
    sendNext(sink, numberProducer.startOn(QueueScheduler()))
    sendCompleted(sink)
    
    let disposable = flattened.startWithNext {
        print($0)
    }
    disposable.dispose()
    

    Output:

    doing work: a
    doing work: 1
    doing work: b
    doing work: 2
    doing work: c
    doing work: 3
    
    Reviewed by bdolman at 2015-10-09 00:08
  • 9. Visual Identity Refresh for 4.0

    I've been meaning to open this issue for a while, but kept finding excuses, mainly the fact that 3.0 was far from release. That is no longer the case now.

    Basically, I'd like to spearhead an effort to revamp the visual identity of RC and hopefully be done with that in time with the 3.0 final release.

    For reference, here is the current logo/color palette: screenshot-2015-07-19-1

    I've played with the concept below a while ago, but I restarted from scratch recently after having talked to @jspahrsummers during WWDC.

    screenshot-11-14-1

    Here are some of the recent sketches to get the creative juices flowing:

    screenshot-2015-07-19

    I'll be detailing the rest of the process in this thread.

    Reviewed by kaishin at 2015-07-19 11:55
  • 10. monad, RACSequence

    #89

    Added a lazy RACSequence class, and abstracted common APIs between it and <RACSubscribable> into a new <RACStream> protocol. I'm definitely open to better names for these guys.

    RAC should be tagged before this gets merged in.

    Reviewed by jspahrsummers at 2012-11-01 08:50
  • 11. The future of RAC 3.0

    Given recent developments, how much should we allow ourselves to disregard backwards compatibility in our next release?

    Is there any part of the RAC contract you would like to change or get rid of?

    For example I would like to take a much more relaxed approach to evaluation, like Rx with its "you cannot assume anything about what scheduler your blocks run on unless you specify a scheduler" caveat.

    On one side it would allow us to optimize for certain use cases much more aggressively, but even better it would promote functional purity when using the framework. What I want is for the lack of strict evaluation semantics not to force users of the framework to do their own serialization and rescheduling of the blocks, but rather to allow them to not care about when, where and how the blocks are executed, because the blocks would be pure functions.

    I realize this can't be done because even in Swift there is no way to specify side effects or lack thereof in the type, or even thread-safety or atomicity, so I'm not suggesting we do this since it would be very confusing for the users, it's just an example of what I mean by changes in the contract.

    I'm sure someone has more reasonable ideas on the matter.

    Reviewed by Coneko at 2014-06-04 16:23
  • 12. Fixed build phases order in target

    See Xcode 10's known issues in the release notes:

    Targets with Copy Headers build phases ordered after Compile Sources build phases may fail to build and emit a diagnostic regarding build cycles. (39880168) Workaround: Arrange any Copy Headers build phases before Compile Sources build phases.

    This has been an issue for nearly 4 years, and now with Xcode 13.3 it leads to XCBBuildService to crash consistently.

    Reviewed by NachoSoto at 2022-04-18 18:12
  • 13. Allow NSObject.reactive.signal to also intercept and return the 'return' value of the executed selector.

    Added the includeReturnValue to reactive.signal(for selector: Selector)

    NSObject.reactive.signal(for selector: Selector, includeReturnValue: Bool = false)

    Will add a return value to the end of the array, for each value of the Signal. If the selector does not return a value, than the flag is ignored and no value is appended to the array.

    Checklist

    • [x] Updated CHANGELOG.md.
    Reviewed by mishagray at 2017-12-28 18:51
  • 14. DelegateProxy revamp

    1. Methods would now be automatically implemented. Subclassing is no longer necessary.

    2. DelegateProxy can now be constructed through NSObject.reactive.proxy(forKey:).

    3. Fixed a memory leak due to the use of forwardingTarget(for:) as the fast path of delegate call forwarding.

    4. More DelegateProxy test cases.

    Usage

    extension Reactive where Base: UITableView {
        var proxy: DelegateProxy<UITableViewDelegate> {
            return proxy(forKey: #keyPath(UITableView.delegate))
        }
    }
    

    To-do

    • [x] Evaluate the behaviour of protocols with non-void-returning required methods.
    • [x] Documentations and Implementation Notes.
    • [x] Share implementation with method Interception.
    Reviewed by andersio at 2017-05-27 12:03
  • 15. [WIP] User Interface Recipes

    Please note that this document is very much a work in progress. Some things that I've left to do:

    • [ ] Remove the dependency on https://github.com/neilpa/Rex
    • [ ] Produce an actual example project. (Much of the below code was typed "raw" into my text editor, and likely won't compile.)
    • [ ] Get feedback from people who have been doing this much longer
    • [ ] Fix the TODOs

    There really isn't any sort of "canonical document" for creating UI code using ReactiveCocoa, and that's probably due to the fact that it's difficult to find a single approach or "recipe" that applies to all scenarios. In my own work on Capo and FuzzMeasure over the past 6 months I have found so many different scenarios and examples that forced me to repeatedly question what I was doing.

    Just when I think that I have an approach figured out, I find another handful of new challenges when I move to another part of the UI to work on. For instance, when I built a lot of iOS UI code I found that it was very easy to build static UIs for UITableViewCells and use ViewModels to ensure that I encapsulate the presentation behavior.

    Once I moved to editable controls for the Neptune UI I faced a whole new set of challenges when trying to get values propagated from my ViewModel down into my audio engine, and encapsulating a live-updating visualization (that wasn't needlessly updating the screen while playback wasn't active, also!)

    I feel that this collection of "Recipes" for various UI patterns would be extremely helpful to people that are new to ReactiveCocoa, and folks that might be looking for ideas when discovering new challenges that they haven't faced before.

    Reviewed by liscio at 2016-01-13 18:18
RxReduce is a lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way.
RxReduce is a lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way.

About Architecture concerns RxReduce Installation The key principles How to use RxReduce Tools and dependencies Travis CI Frameworks Platform Licence

Jan 29, 2022
A New, Modern Reactive State Management Library for Swift and SwiftUI (The iOS implementation of Recoil)
A New, Modern Reactive State Management Library for Swift and SwiftUI (The iOS implementation of Recoil)

RecoilSwift RecoilSwift is a lightweight & reactive swift state management library. RecoilSwift is a SwiftUI implementation of recoil.js which powered

May 22, 2022
RxXRepository: reactive extension for XRepository

RxXRepository is reactive extension for XRepository. This extension allows imple

Jan 6, 2022
Spin aims to provide a versatile Feedback Loop implementation working with the three main reactive frameworks available in the Swift community (RxSwift, ReactiveSwift and Combine)
Spin aims to provide a versatile Feedback Loop implementation working with the three main reactive frameworks available in the Swift community (RxSwift, ReactiveSwift and Combine)

With the introduction of Combine and SwiftUI, we will face some transition periods in our code base. Our applications will use both Combine and a thir

May 12, 2022
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

Jun 19, 2022
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Jun 16, 2022
Set of useful extensions for ReactiveSwift & ReactiveCocoa
Set of useful extensions for ReactiveSwift & ReactiveCocoa

ACKReactiveExtensions ACKReactiveExtensions is set of useful extensions for ReactiveCocoa you could use in your apps. Currently we have extensions for

Mar 12, 2022
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Jun 16, 2022
Model framework for Cocoa and Cocoa Touch

Mantle Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application. The Typical Model Object What's wrong with the wa

Jun 22, 2022
Adding ruby style each iterator to Cocoa/Cocoa touch Swift Array and Range classes, And Int.times{} to Int class

Collection-Each Adding ruby style each iterator to Cocoa/Cocoa touch Swift Array, Dictionary and Range classes, and Int.times ###Why? Array/Dictionary

Jun 9, 2018
Reactive WebSockets - A lightweight abstraction layer over Starscream to make it reactive.

RxWebSocket Reactive extensions for websockets. A lightweight abstraction layer over Starscream to make it reactive. Installation RxWebSocket is avail

Mar 1, 2022
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.

ZamzamKit ZamzamKit is a Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and othe

Jun 17, 2022
Swift JSExport extensions for macOS system frameworks
Swift JSExport extensions for macOS system frameworks

framework-bridge Swift JSExport extensions for macOS system frameworks. Progress Foundation AppKit Usage Swift import JavaScriptCore import FrameworkB

Dec 13, 2021
Allows users to pull in new song releases from their favorite artists and provides users with important metrics like their top tracks, top artists, and recently played tracks, queryable by time range.

Spotify Radar Spotify Radar is an iOS application that allows users to pull in new song releases from their favorite artists and provides users with i

Jun 19, 2022
A reactive, card-based UI framework built on UIKit for iOS developers.
A reactive, card-based UI framework built on UIKit for iOS developers.

CardParts - made with ❤️ by Intuit: Example Requirements Installation Communication & Contribution Overview Quick Start Architecture CardsViewControll

Jun 14, 2022
A reactive wrapper built around UIImagePickerController.

RxMediaPicker RxMediaPicker is a RxSwift wrapper built around UIImagePickerController consisting in a simple interface for common actions like picking

Apr 24, 2022
Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).
Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).

Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD). It allows you to create any asynchronous and synchronous task easily, all managed by a queue, with just a few lines.

Jun 18, 2022
Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.
 Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.

Zip A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip. Usage Import Zip at the top of the Swift file

Jun 17, 2022
A swift network profiler built on top of URLSession.
A swift network profiler built on top of URLSession.

By Xmartlabs SRL. Introduction Xniffer is a non-intrusive framework for intercepting outgoing requests and their responses between your app and any ex

May 21, 2022
iOS Simulator type agnostic snapshot testing, built on top of the FBSnapshotTestCase.
iOS Simulator type agnostic snapshot testing, built on top of the FBSnapshotTestCase.

SnappyTestCase iOS Simulator type agnostic snapshot testing, built on top of the FBSnapshotTestCase. Why? Snapshot testing helps to deliver views that

Oct 11, 2019