Convert Figma logo to code with AI

ReactiveCocoa logoReactiveCocoa

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

19,923
3,456
19,923
9

Top Related Projects

24,441

Reactive Programming in Swift

Async Algorithms for Swift

4,229

A Swift binding framework

7,565

Unidirectional Data Flow in Swift - Inspired by Redux

15,190

Network abstraction layer written in Swift.

Quick Overview

ReactiveCocoa is a reactive programming framework for iOS and macOS development. It provides a set of tools and abstractions for composing and transforming streams of values over time, allowing developers to write more declarative and functional code for handling asynchronous events and data flows.

Pros

  • Simplifies complex asynchronous operations and UI interactions
  • Promotes a more declarative and functional programming style
  • Provides powerful operators for transforming and combining streams of data
  • Integrates well with Swift and Objective-C codebases

Cons

  • Steep learning curve for developers new to reactive programming
  • Can lead to overly complex code if not used judiciously
  • Documentation can be challenging to navigate for beginners
  • Performance overhead in some scenarios compared to traditional imperative code

Code Examples

  1. Creating and subscribing to a signal:
let (signal, observer) = Signal<String, Never>.pipe()

signal.observe { event in
    switch event {
    case .value(let string):
        print("Received value: \(string)")
    case .completed:
        print("Signal completed")
    }
}

observer.send(value: "Hello, ReactiveCocoa!")
observer.sendCompleted()
  1. Transforming signals:
let numbers = Signal<Int, Never>.pipe()
let doubledNumbers = numbers.map { $0 * 2 }

doubledNumbers.observeValues { value in
    print("Doubled number: \(value)")
}

numbers.send(value: 5)  // Prints: Doubled number: 10
numbers.send(value: 8)  // Prints: Doubled number: 16
  1. Combining signals:
let (signal1, observer1) = Signal<String, Never>.pipe()
let (signal2, observer2) = Signal<String, Never>.pipe()

Signal.combineLatest(signal1, signal2)
    .observeValues { (value1, value2) in
        print("Combined values: \(value1), \(value2)")
    }

observer1.send(value: "Hello")
observer2.send(value: "World")  // Prints: Combined values: Hello, World
observer1.send(value: "Reactive")  // Prints: Combined values: Reactive, World

Getting Started

To get started with ReactiveCocoa, add it to your project using Swift Package Manager:

  1. In Xcode, go to File > Swift Packages > Add Package Dependency
  2. Enter the repository URL: https://github.com/ReactiveCocoa/ReactiveCocoa.git
  3. Select the version you want to use

Then, import ReactiveCocoa in your Swift file:

import ReactiveCocoa

Now you can start using ReactiveCocoa's reactive programming features in your iOS or macOS project.

Competitor Comparisons

24,441

Reactive Programming in Swift

Pros of RxSwift

  • More extensive documentation and learning resources
  • Larger community and ecosystem
  • Cross-platform compatibility with other Rx implementations

Cons of RxSwift

  • Steeper learning curve for developers new to reactive programming
  • Slightly more verbose syntax compared to ReactiveCocoa

Code Comparison

ReactiveCocoa:

let searchResults = searchText.producer
    .debounce(0.3, on: QueueScheduler.main)
    .flatMap(.latest) { text in
        return API.search(text)
    }

RxSwift:

let searchResults = searchText
    .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
    .flatMapLatest { text in
        return API.search(text)
    }

Both ReactiveCocoa and RxSwift are powerful reactive programming frameworks for Swift. ReactiveCocoa, being Swift-native, offers a more idiomatic Swift experience and easier integration with Apple's frameworks. RxSwift, on the other hand, provides better cross-platform compatibility and a larger ecosystem due to its connection with the broader ReactiveX project.

The code comparison shows that both frameworks have similar syntax for common operations like debouncing and flatMapping. ReactiveCocoa uses producer for signals, while RxSwift uses observables directly. The choice between the two often comes down to personal preference, existing team expertise, and specific project requirements.

Async Algorithms for Swift

Pros of swift-async-algorithms

  • Native integration with Swift's async/await concurrency model
  • Officially supported by Apple, ensuring long-term compatibility
  • Designed specifically for Swift, optimizing performance and language features

Cons of swift-async-algorithms

  • Limited to Swift ecosystem, not cross-platform like ReactiveCocoa
  • Newer project with potentially fewer community resources and examples
  • Focuses solely on async algorithms, while ReactiveCocoa offers a broader reactive programming framework

Code Comparison

ReactiveCocoa:

let searchResults = searchTextField.reactive.continuousTextValues
    .throttle(0.3, on: QueueScheduler.main)
    .flatMap(.latest) { text in
        return API.search(text)
    }

swift-async-algorithms:

let searchResults = searchTextField.textPublisher
    .debounce(for: .seconds(0.3))
    .asyncMap { text in
        try await API.search(text)
    }

Both examples demonstrate similar functionality, but swift-async-algorithms leverages Swift's native async/await syntax, while ReactiveCocoa uses its own reactive programming paradigm. The swift-async-algorithms approach may be more intuitive for developers already familiar with Swift's concurrency model, while ReactiveCocoa offers a more comprehensive reactive programming solution that extends beyond async operations.

4,229

A Swift binding framework

Pros of Bond

  • Simpler syntax and more intuitive API for Swift developers
  • Better integration with SwiftUI and Combine frameworks
  • Lighter weight and faster performance in some scenarios

Cons of Bond

  • Less mature and smaller community compared to ReactiveCocoa
  • Fewer features and extensions available
  • Limited support for Objective-C projects

Code Comparison

Bond:

let text = Observable<String?>("")
text.bind(to: label.reactive.text)

ReactiveCocoa:

let text = MutableProperty<String?>("")
label.reactive.text <~ text

Both libraries provide reactive programming capabilities for iOS development, but they differ in their approach and target audience. Bond is more focused on Swift and modern Apple frameworks, while ReactiveCocoa has a longer history and broader language support.

Bond's syntax is often considered more straightforward for Swift developers, especially those familiar with SwiftUI and Combine. However, ReactiveCocoa's larger community and extensive feature set may be advantageous for complex projects or those requiring Objective-C support.

The code comparison demonstrates the slight differences in syntax between the two libraries. Bond uses a more explicit bind(to:) method, while ReactiveCocoa employs custom operators like <~ for binding.

Ultimately, the choice between Bond and ReactiveCocoa depends on project requirements, team expertise, and personal preference.

7,565

Unidirectional Data Flow in Swift - Inspired by Redux

Pros of ReSwift

  • Simpler architecture based on Redux, making it easier to understand and implement
  • Better suited for small to medium-sized projects
  • Provides a clear, unidirectional data flow, which can lead to more predictable state management

Cons of ReSwift

  • Less flexible compared to ReactiveCocoa's reactive programming paradigm
  • May require more boilerplate code for complex scenarios
  • Limited built-in operators and transformations compared to ReactiveCocoa

Code Comparison

ReSwift:

struct AppState: StateType {
    var counter: Int = 0
}

struct IncrementAction: Action {}

func counterReducer(action: Action, state: AppState?) -> AppState {
    var state = state ?? AppState()
    switch action {
    case _ as IncrementAction:
        state.counter += 1
    default:
        break
    }
    return state
}

ReactiveCocoa:

let (counterSignal, counterObserver) = Signal<Int, NoError>.pipe()
let incrementAction = Action<Void, Void, NoError> { _ in
    return SignalProducer { observer, _ in
        counterObserver.send(value: counterValue + 1)
        observer.sendCompleted()
    }
}

ReSwift focuses on a more straightforward approach with explicit state and actions, while ReactiveCocoa provides a more flexible, reactive programming model with signals and observers.

15,190

Network abstraction layer written in Swift.

Pros of Moya

  • Simplifies network abstraction layer with a clean, declarative approach
  • Provides built-in support for testing and stubbing network requests
  • Offers easy integration with popular Swift frameworks like RxSwift and PromiseKit

Cons of Moya

  • Steeper learning curve for developers new to protocol-oriented programming
  • May introduce unnecessary complexity for simple API integrations
  • Limited flexibility compared to ReactiveCocoa for non-networking reactive programming tasks

Code Comparison

Moya:

let provider = MoyaProvider<MyService>()
provider.request(.userProfile) { result in
    switch result {
    case let .success(response):
        let data = response.data
        // Handle the response data
    case let .failure(error):
        // Handle the error
    }
}

ReactiveCocoa:

let (signal, observer) = Signal<Data, Error>.pipe()
URLSession.shared.dataTask(with: url) { data, response, error in
    if let data = data {
        observer.send(value: data)
    } else if let error = error {
        observer.send(error: error)
    }
}.resume()

Both ReactiveCocoa and Moya are powerful libraries for iOS development, but they serve different purposes. ReactiveCocoa is a more general-purpose reactive programming framework, while Moya focuses specifically on network abstraction. The choice between the two depends on the project's specific needs and the development team's preferences.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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:

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.