ReactiveCocoa

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 [BindingTarget][]s, 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 [Signal][]s for control events
    and updates in the control value upon user interactions.

    A selected set of controls provide a convenience, expressive binding
    API for [Action][]s.

    // 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 [SignalProducer][]s 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:

github "ReactiveCocoa/ReactiveCocoa" ~> 8.0

If you use Carthage to build your dependencies, make sure you have added ReactiveCocoa.framework, ReactiveSwift.framework, and Result.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', '~> 8.0'

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,
    Carthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj, and
    Carthage/Checkouts/Result/Result.xcodeproj into your application’s Xcode
    project or workspace.
  4. On the “General” tab of your application target’s settings, add
    ReactiveCocoa.framework, ReactiveSwift.framework, and Result.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”.

GitHub