Top Related Projects
Reactive Programming in Swift
Async Algorithms for Swift
A Swift binding framework
Unidirectional Data Flow in Swift - Inspired by Redux
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
- 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()
- 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
- 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:
- In Xcode, go to File > Swift Packages > Add Package Dependency
- Enter the repository URL: https://github.com/ReactiveCocoa/ReactiveCocoa.git
- 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
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.
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.
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.
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
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.
â ï¸ Looking for the Objective-C API?
ð 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.
-
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. -
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)
-
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)
-
Expressive, Safe Key Path Observation
Establish key-value observations in the form of
SignalProducer
s andDynamicProperty
s, 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
- Add the ReactiveCocoa repository as a submodule of your applicationâs repository.
- Run
git submodule update --init --recursive
from within the ReactiveCocoa folder. - Drag and drop
ReactiveCocoa.xcodeproj
andCarthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj
into your applicationâs Xcode project or workspace. - On the âGeneralâ tab of your application targetâs settings, add
ReactiveCocoa.framework
andReactiveSwift.framework
to the âEmbedded Binariesâ section. - 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
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.
Top Related Projects
Reactive Programming in Swift
Async Algorithms for Swift
A Swift binding framework
Unidirectional Data Flow in Swift - Inspired by Redux
Network abstraction layer written in Swift.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot