### Subscribing to an Observable in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates how subscribing to an Observable triggers the sequence generation. The initial assignment of the Observable does no work, but calling `.subscribe` initiates the process defined by the Observable, such as firing network requests in this example. ```Swift let searchForMe = searchWikipedia("me") // no requests are performed, no work is being done, no URL requests were fired let cancel = searchForMe // sequence generation starts now, URL requests are fired .subscribe(onNext: { results in print(results) }) ``` -------------------------------- ### Creating URLRequest - Foundation - Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates the creation of a simple `URLRequest` object in Swift using a URL string. This object represents the configuration for an HTTP request, including the URL, method (GET by default), and other properties. It's the first step before executing an HTTP request. ```Swift let req = URLRequest(url: URL(string: "http://en.wikipedia.org/w/api.php?action=parse&page=Pizza&format=json")) ``` -------------------------------- ### Initializing DisposeBag Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates how to initialize a `DisposeBag`. When a `DisposeBag` is deallocated, it automatically calls `dispose` on all subscriptions added to it, providing ARC-like behavior for resource management. ```swift self.disposeBag = DisposeBag() ``` -------------------------------- ### Standard Subscription Pattern in RxSwift (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Illustrates a standard way to subscribe to an observable sequence ('kittens') and handle '.next' events within the Rx monad. It shows how to dispose of the subscription using a 'DisposeBag'. Requires RxSwift and a 'DisposeBag'. ```Swift kittens .subscribe(onNext: { kitten in // do something with kitten }) .disposed(by: disposeBag) ``` -------------------------------- ### Observe UIView Frame using `rx.observeWeakly` (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This example shows an alternative way to observe the `frame` property of a `UIView` using `rx.observeWeakly`. Similar to `rx.observe`, it creates an `Observable` emitting `CGRect` values on frame changes, but uses the weakly observing mechanism. ```Swift view .rx.observeWeakly(CGRect.self, "frame") .subscribe(onNext: { frame in ... }) ``` -------------------------------- ### Subscribing to a Custom `just` Observable in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates how to subscribe to the custom `myJust` Observable created in the previous snippet. Subscribing triggers the Observable to emit the single element (0) and then complete, resulting in the element being printed to the console. ```Swift myJust(0) .subscribe(onNext: { n in print(n) }) ``` -------------------------------- ### Manual Subscription Disposal with interval Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates how to manually dispose of a subscription created with the `interval` operator. This is shown for educational purposes to illustrate resource cleanup, but manual disposal is generally discouraged in favor of automatic mechanisms. ```swift let scheduler = SerialDispatchQueueScheduler(qos: .default) let subscription = Observable.interval(.milliseconds(300), scheduler: scheduler) .subscribe { event in print(event) } Thread.sleep(forTimeInterval: 2.0) subscription.dispose() ``` -------------------------------- ### Defining RxSwift Observer Protocol (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This snippet defines the `ObserverType` protocol, which specifies the `on` method used by an observer to receive events (`next`, `error`, or `completed`) pushed by an `Observable` sequence. ```Swift protocol ObserverType { func on(_ event: Event) } ``` -------------------------------- ### Handling URLSession Response with rx.response - RxCocoa - Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Provides an example of using RxCocoa's `URLSession.shared.rx.response` extension for lower-level access to the HTTP response, yielding a `(data: NSData, response: URLResponse)` tuple. It demonstrates how to use `flatMap` to process the response, check the HTTP status code (200-299 for success), transform the data, and return either a success observable or an error observable. Includes `debug` operator usage. ```Swift URLSession.shared.rx.response(myURLRequest) .debug("my request") // this will print out information to console .flatMap { (data: NSData, response: URLResponse) -> Observable in if let response = response as? HTTPURLResponse { if 200 ..< 300 ~= response.statusCode { return just(transform(data)) } else { return Observable.error(yourNSError) } } else { rxFatalError("response = nil") return Observable.error(yourNSError) } } .subscribe { event in print(event) // if error happened, this will also print out error to console } ``` -------------------------------- ### Run RxSwift Examples with CocoaPods Source: https://github.com/reactivex/rxswift/blob/main/Documentation/ExampleApp.md This command uses CocoaPods to download and open the RxSwift example project, allowing users to quickly try out the library's examples without cloning the full repository. ```Shell pod try RxSwift ``` -------------------------------- ### Periodically Print Resource Count for Leak Detection (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This snippet demonstrates how to use `Observable.interval` to periodically print the total resource count tracked by RxSwift. This helps in debugging potential memory leaks by observing changes in the resource count over time. It should be placed in the application's setup code, like `didFinishLaunchingWithOptions`. ```Swift /* add somewhere in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) */ _ = Observable.interval(.seconds(1), scheduler: MainScheduler.instance) .subscribe(onNext: { _ in print("Resource count \(RxSwift.Resources.total)") }) ``` -------------------------------- ### Running CocoaPods Installation (Bash) Source: https://github.com/reactivex/rxswift/blob/main/README.md This command executes the CocoaPods installation process based on the `Podfile` in the current directory. It downloads and integrates the specified pods into the Xcode project workspace. ```Bash pod install ``` -------------------------------- ### Observe Arbitrary Object Property using `rx.observeWeakly` (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This example shows how `rx.observeWeakly` can be used to observe a property (`behavingOk`) on an arbitrary object (`someSuspiciousViewController`) whose ownership relationship is unknown. This method is suitable for observing weak properties or objects outside the direct ownership graph. ```Swift someSuspiciousViewController.rx.observeWeakly(Bool.self, "behavingOk") ``` -------------------------------- ### Subscribing Multiple Times to a Custom `from` Observable in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows how subscribing multiple times to the same custom `myFrom` Observable triggers the sequence generation independently for each subscription. This highlights the nature of cold Observables, where each subscriber receives the full sequence from the beginning. ```Swift let stringCounter = myFrom(["first", "second"]) print("Started ----") // first time stringCounter .subscribe(onNext: { n in print(n) }) print("----") // again stringCounter .subscribe(onNext: { n in print(n) }) print("Ended ----") ``` -------------------------------- ### Implementing `just` Operator with `create` in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows a manual implementation of the `just` operator using `Observable.create`. This custom operator creates an Observable that emits a single element upon subscription and then immediately completes. It demonstrates the basic structure of using `create` to define sequence behavior. ```Swift func myJust(_ element: E) -> Observable { return Observable.create { observer in observer.on(.next(element)) observer.on(.completed) return Disposables.create() } } ``` -------------------------------- ### Installing xcbeautify Dependency via Homebrew Source: https://github.com/reactivex/rxswift/blob/main/CONTRIBUTING.md Provides the command using Homebrew to install `xcbeautify`, a required dependency for running the test script `./scripts/all-tests.sh`. ```Shell brew install xcbeautify ``` -------------------------------- ### Implementing `from` Operator with `create` in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Provides a manual implementation of the `from` operator using `Observable.create`. This custom operator creates an Observable that iterates over an array and emits each element sequentially upon subscription before completing. It further illustrates using `create` for synchronous sequence generation. ```Swift func myFrom(_ sequence: [E]) -> Observable { return Observable.create { observer in for element in sequence { observer.on(.next(element)) } observer.on(.completed) return Disposables.create() } } ``` -------------------------------- ### Executing URLRequest with rx.json - RxCocoa - Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Illustrates how to use RxCocoa's `URLSession.shared.rx.json` extension to create an observable that fetches JSON data from a given `URLRequest`. The request is only fired upon subscription. The example also shows how to subscribe to the observable to trigger the request and how to dispose of the subscription to cancel the ongoing request. Note that results are not on the main thread by default. ```Swift let responseJSON = URLSession.shared.rx.json(request: req) // no requests will be performed up to this point // `responseJSON` is just a description how to fetch the response let cancelRequest = responseJSON // this will fire the request .subscribe(onNext: { json in print(json) }) Thread.sleep(forTimeInterval: 3.0) // if you want to cancel request after 3 seconds have passed just call cancelRequest.dispose() ``` -------------------------------- ### Observe UIView Frame using `rx.observe` (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This example demonstrates how to use `rx.observe` to create an `Observable` that emits the `frame` property of a `UIView` whenever it changes. The observable emits `CGRect` values. Although UIKit is not fully KVO compliant, this specific observation typically works. ```Swift view .rx.observe(CGRect.self, "frame") .subscribe(onNext: { frame in ... }) ``` -------------------------------- ### Customizing URLSession Logging - RxCocoa - Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Explains how to override the `URLSession.rx.shouldLogRequest` closure to control which HTTP requests are logged to the console by RxCocoa when running in debug mode. The example shows how to filter logging based on the request URL's host, only logging requests to "reactivex.org". ```Swift URLSession.rx.shouldLogRequest = { request in // Only log requests to reactivex.org return request.url?.host == "reactivex.org" || request.url?.host == "www.reactivex.org" } ``` -------------------------------- ### Debugging Runtime Behavior - Using debug Operator Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md The built-in `debug` operator acts as a probe, printing all events (subscribe, next, error, completed, dispose) passing through it to standard output. You can provide an optional label to distinguish output from different probes in your code. ```swift let subscription = myInterval(.milliseconds(100)) .debug("my probe") .map { e in return "This is simply \(e)" } .subscribe(onNext: { n in print(n) }) Thread.sleepForTimeInterval(0.5) subscription.dispose() ``` -------------------------------- ### Defining an Observable Function in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Defines a placeholder function signature that returns an `Observable`. This illustrates the typical pattern of functions that produce Observable sequences, emphasizing that calling the function itself does not trigger any work. ```Swift func searchWikipedia(searchTerm: String) -> Observable {} ``` -------------------------------- ### RxSwift KVO `observe` and `observeWeakly` Method Definitions (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md These Swift extensions define the `observe` and `observeWeakly` methods on the `Reactive` wrapper for `NSObject`. They provide reactive wrappers around the Objective-C Key-Value Observing (KVO) mechanism, allowing observation of key paths as `Observable` sequences. ```Swift // KVO extension Reactive where Base: NSObject { public func observe(type: E.Type, _ keyPath: String, options: KeyValueObservingOptions, retainSelf: Bool = true) -> Observable {} } #if !DISABLE_SWIZZLING // KVO extension Reactive where Base: NSObject { public func observeWeakly(type: E.Type, _ keyPath: String, options: KeyValueObservingOptions) -> Observable {} } #endif ``` -------------------------------- ### Implementing Autocomplete Search with RxSwift (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Why.md Provides a comprehensive example of implementing an autocomplete search feature using RxSwift, including throttling input, filtering duplicate queries, canceling previous requests (`flatMapLatest`), retrying failed API calls, providing initial empty results, and handling errors. Requires a `DisposeBag`. ```Swift searchTextField.rx.text .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .distinctUntilChanged() .flatMapLatest { query in API.getSearchResults(query) .retry(3) .startWith([]) // clears results on new search term .catchErrorJustReturn([]) } .subscribe(onNext: { results in // bind to ui }) .disposed(by: disposeBag) ``` -------------------------------- ### Defining RxSwift Event and Observable Types (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This snippet defines the fundamental `Event` enumeration used to represent sequence elements, errors, or completion, and the basic `Observable` class structure with its `subscribe` method, illustrating the push-based nature of Rx sequences. ```Swift enum Event { case next(Element) // next element of a sequence case error(Swift.Error) // sequence failed with error case completed // sequence terminated successfully } class Observable { func subscribe(_ observer: Observer) -> Disposable } ``` -------------------------------- ### Subscribing and Disposing Single Interval Observable (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Subscribes to the `myInterval` observable with a 100ms interval. It prints the emitted numbers. After 0.5 seconds, the subscription is explicitly disposed, stopping the timer and emissions. ```swift let counter = myInterval(.milliseconds(100)) print("Started ----") let subscription = counter .subscribe(onNext: { n in print(n) }) Thread.sleep(forTimeInterval: 0.5) subscription.dispose() print("Ended ----") ``` -------------------------------- ### Multiple Independent Subscriptions to Custom Interval Observable (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Creates two separate subscriptions to the same `myInterval` observable. Each subscription triggers a new underlying timer and receives its own sequence of numbers, demonstrating the default stateless behavior of `Observable.create`. ```swift let counter = myInterval(.milliseconds(100)) print("Started ----") let subscription1 = counter .subscribe(onNext: { n in print("First \(n)") }) let subscription2 = counter .subscribe(onNext: { n in print("Second \(n)") }) Thread.sleep(forTimeInterval: 0.5) subscription1.dispose() print("Disposed") Thread.sleep(forTimeInterval: 0.5) subscription2.dispose() print("Disposed") print("Ended ----") ``` -------------------------------- ### Installing RxSwift/RxCocoa with CocoaPods (Ruby) Source: https://github.com/reactivex/rxswift/blob/main/README.md This Podfile configuration specifies the dependencies for a project using CocoaPods. It includes `RxSwift` and `RxCocoa` for the main application target and `RxBlocking` and `RxTest` for the testing target, both locked to version '6.9.0'. ```Ruby # Podfile use_frameworks! target 'YOUR_TARGET_NAME' do pod 'RxSwift', '6.9.0' pod 'RxCocoa', '6.9.0' end # RxTest and RxBlocking make the most sense in the context of unit/integration tests target 'YOUR_TESTING_TARGET' do pod 'RxBlocking', '6.9.0' pod 'RxTest', '6.9.0' end ``` -------------------------------- ### Implementing Username Validation with RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Examples.md Demonstrates a complete RxSwift chain for validating a username entered into a text field. It includes defining validation states, performing an initial synchronous check, triggering an asynchronous API call to check availability, showing a pending state while the API call is in progress, canceling previous API calls when the input changes using `switchLatest`, and updating UI labels with the validation result and message. Resource management is handled automatically using a `DisposeBag`. ```Swift enum Availability {\n case available(message: String)\n case taken(message: String)\n case invalid(message: String)\n case pending(message: String)\n\n var message: String {\n switch self {\n case .available(let message),\n .taken(let message),\n .invalid(let message),\n .pending(let message): \n\n return message\n }\n }\n}\n\n// bind UI control values directly\n// use username from `usernameOutlet` as username values source\nself.usernameOutlet.rx.text\n .map { username -> Observable in\n\n // synchronous validation, nothing special here\n guard let username = username, !username.isEmpty else {\n // Convenience for constructing synchronous result.\n // In case there is mixed synchronous and asynchronous code inside the same\n // method, this will construct an async result that is resolved immediately.\n return Observable.just(.invalid(message: "Username can't be empty."))\n }\n\n // ...\n\n // User interfaces should probably show some state while async operations\n // are executing.\n let loadingValue = Availability.pending(message: "Checking availability ...")\n\n // This will fire a server call to check if the username already exists.\n // Its type is `Observable`\n return API.usernameAvailable(username)\n .map { available in\n if available {\n return .available(message: "Username available")\n }\n else {\n return .taken(message: "Username already taken")\n }\n }\n // use `loadingValue` until server responds\n .startWith(loadingValue)\n }\n// Since we now have `Observable>`\n// we need to somehow return to a simple `Observable`.\n// We could use the `concat` operator from the second example, but we really\n// want to cancel pending asynchronous operations if a new username is provided.\n// That's what `switchLatest` does.\n .switchLatest()\n// Now we need to bind that to the user interface somehow.\n// Good old `subscribe(onNext:)` can do that.\n// That's the end of `Observable` chain.\n .subscribe(onNext: { [weak self] validity in\n self?.errorLabel.textColor = validationColor(validity)\n self?.errorLabel.text = validity.message\n })\n// This will produce a `Disposable` object that can unbind everything and cancel\n// pending async operations.\n// Instead of doing it manually, which is tedious,\n// let's dispose everything automagically upon view controller dealloc.\n .disposed(by: disposeBag) ``` -------------------------------- ### Manual Dispose after observeOn (Main Thread) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Illustrates disposing a subscription on the main thread after the observable sequence has been observed on the `MainScheduler`. This scenario guarantees that no events will be printed after the `dispose` call returns. ```swift let subscription = Observable.interval(.milliseconds(300), scheduler: scheduler) .observe(on: MainScheduler.instance) .subscribe { event in print(event) } // .... subscription.dispose() // called from main thread ``` -------------------------------- ### Observable Sequential Event Guarantee Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Illustrates the guarantee that Observables process events sequentially. An Observable will not send the next element until the observer's `on` method has finished executing for the current element. ```swift someObservable .subscribe { (e: Event) in print("Event processing started") // processing print("Event processing ended") } ``` -------------------------------- ### Observe Nested Key Path with `rx.observe` and `retainSelf: false` (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This snippet demonstrates using `rx.observe` to observe a nested key path, specifically the `frame` of a `view` property on `self`. Setting `retainSelf: false` is suitable for observing paths starting from `self` or its ancestors in the ownership graph. ```Swift self.rx.observe(CGRect.self, "view.frame", retainSelf: false) ``` -------------------------------- ### Basic Search Query Binding with RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Traits.md A typical beginner example demonstrating how to throttle user input from a text field, fetch autocomplete results, and bind them to a table view and a count label. This approach is shown to have potential issues with error handling, threading, and duplicate network requests. ```Swift let results = query.rx.text .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .flatMapLatest { query in fetchAutoCompleteItems(query) } results .map { "\($0.count)" } .bind(to: resultCount.rx.text) .disposed(by: disposeBag) results .bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in cell.textLabel?.text = "\(result)" } .disposed(by: disposeBag) ``` -------------------------------- ### Exiting and Re-entering Rx Monad with Subjects (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates a pattern (considered a "bad code smell") where an observable stream is subscribed to (exiting the monad), imperative code is executed, and results are fed back into Rx using a 'BehaviorRelay' (re-entering the monad). Requires RxSwift and a 'DisposeBag'. ```Swift let magicBeings: Observable = summonFromMiddleEarth() magicBeings .subscribe(onNext: { being in // exit the Rx monad self.doSomeStateMagic(being) }) .disposed(by: disposeBag) // // Mess // let kitten = globalParty( // calculate something in messy world being, UIApplication.delegate.dataSomething.attendees ) kittens.on(.next(kitten)) // send result back to rx // // Another mess // let kittens = BehaviorRelay(value: firstKitten) // again back in Rx monad kittens.asObservable() .map { kitten in return kitten.purr() } // .... ``` -------------------------------- ### Creating Observable for URLSession Data Task (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Extends `URLSession` to provide a reactive `response` function. It creates an `Observable` that performs a data task. Upon completion, it emits the `HTTPURLResponse` and `Data` as a tuple or an error. Disposing the subscription cancels the data task. ```swift extension Reactive where Base: URLSession { public func response(request: URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)> { return Observable.create { observer in let task = self.base.dataTask(with: request) { (data, response, error) in guard let response = response, let data = data else { observer.on(.error(error ?? RxCocoaURLError.unknown)) return } guard let httpResponse = response as? HTTPURLResponse else { observer.on(.error(RxCocoaURLError.nonHTTPResponse(response: response))) return } observer.on(.next((httpResponse, data))) observer.on(.completed) } task.resume() return Disposables.create { task.cancel() } } } } ``` -------------------------------- ### Debugging Runtime Behavior - Custom Debug Operator Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md You can create your own custom debug operator by extending `ObservableType`. This allows you to control exactly what information is printed or logged for events, subscriptions, and disposals, tailoring the debugging output to your specific needs. ```swift extension ObservableType { public func myDebug(identifier: String) -> Observable { return Observable.create { observer in print("subscribed \(identifier)") let subscription = self.subscribe { e in print("event \(identifier) \(e)") switch e { case .next(let value): observer.on(.next(value)) case .error(let error): observer.on(.error(error)) case .completed: observer.on(.completed) } } return Disposables.create { print("disposing \(identifier)") subscription.dispose() } } } } ``` -------------------------------- ### Sharing Subscription with share(replay:1) Operator (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Applies the `share(replay: 1)` operator to the `myInterval` observable. Multiple subscriptions now share a single underlying timer. New subscribers receive the last emitted value immediately and then subsequent values from the shared sequence. ```swift let counter = myInterval(.milliseconds(100)) .share(replay: 1) print("Started ----") let subscription1 = counter .subscribe(onNext: { n in print("First \(n)") }) let subscription2 = counter .subscribe(onNext: { n in print("Second \(n)") }) Thread.sleep(forTimeInterval: 0.5) subscription1.dispose() Thread.sleep(forTimeInterval: 0.5) subscription2.dispose() print("Ended ----") ``` -------------------------------- ### Disposing with takeUntil operator Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows how to use the `takeUntil` operator to automatically dispose of a subscription when another observable sequence emits an element. This is commonly used with `rx.deallocated` to dispose subscriptions when an object is deallocated. ```swift sequence .take(until: self.rx.deallocated) .subscribe { print($0) } ``` -------------------------------- ### Creating Custom Interval Observable with DispatchSource (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Defines a function `myInterval` that returns an `Observable`. It uses `DispatchSource.makeTimerSource` to schedule events on a global queue. The observer receives sequential integers (`next`) at the specified interval. Disposing the subscription cancels the timer. ```swift func myInterval(_ interval: DispatchTimeInterval) -> Observable { return Observable.create { observer in print("Subscribed") let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()) timer.schedule(deadline: DispatchTime.now() + interval, repeating: interval) let cancel = Disposables.create { print("Disposed") timer.cancel() } var next = 0 timer.setEventHandler { if cancel.isDisposed { return } observer.on(.next(next)) next += 1 } timer.resume() return cancel } } ``` -------------------------------- ### Creating Reactive Values with RxSwift in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Examples.md Demonstrates using RxSwift `BehaviorRelay` and `Observable.combineLatest` to create a reactive binding where `c` automatically updates based on changes to `a` and `b`. It includes filtering and mapping the combined values and subscribing to print updates. ```Swift let a /*: Observable*/ = BehaviorRelay(value: 1) // a = 1 let b /*: Observable*/ = BehaviorRelay(value: 2) // b = 2 // Combines latest values of relays `a` and `b` using `+` let c = Observable.combineLatest(a, b) { $0 + $1 } .filter { $0 >= 0 } // if `a + b >= 0` is true, `a + b` is passed to the map operator .map { "\($0) is positive" } // maps `a + b` to "\(a + b) is positive" // Since the initial values are a = 1 and b = 2 // 1 + 2 = 3 which is >= 0, so `c` is initially equal to "3 is positive" // To pull values out of the Rx `Observable` `c`, subscribe to values from `c`. // `subscribe(onNext:)` means subscribe to the next (fresh) values of `c`. // That also includes the initial value "3 is positive". c.subscribe(onNext: { print($0) }) // prints: "3 is positive" // Now, let's increase the value of `a` a.accept(4) // prints: 6 is positive // The sum of the latest values, `4` and `2`, is now `6`. // Since this is `>= 0`, the `map` operator produces "6 is positive" // and that result is "assigned" to `c`. // Since the value of `c` changed, `{ print($0) }` will get called, // and "6 is positive" will be printed. // Now, let's change the value of `b` b.accept(-8) // doesn't print anything // The sum of the latest values, `4 + (-8)`, is `-4`. // Since this is not `>= 0`, `map` doesn't get executed. // This means that `c` still contains "6 is positive" // Since `c` hasn't been updated, a new "next" value hasn't been produced, // and `{ print($0) }` won't be called. ``` -------------------------------- ### Debugging Compile Errors - Add Argument and Return Type Annotations Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md If adding only return type annotations isn't sufficient, further specify the types of closure arguments. This provides maximum type information to the compiler, making it easier to identify the source of the compile error. ```swift images = word .filter { (s: String) -> Bool in s.containsString("important") } .flatMap { (word: String) -> Observable in return self.api.loadFlickrFeed("karate") .catchError { (error: Error) -> Observable in return just(JSON(1)) } } ``` -------------------------------- ### Manual Dispose after observeOn (Same Serial Scheduler) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows disposing a subscription on the same serial scheduler that the observable sequence is being observed on. Similar to disposing on the main thread, this also guarantees that no events will be printed after the `dispose` call returns. ```swift let subscription = Observable.interval(.milliseconds(300), scheduler: scheduler) .observe(on: MainScheduler.instance) .subscribe { event in print(event) } // ... subscription.dispose() // executing on same `serialScheduler` ``` -------------------------------- ### Creating a Single from an Asynchronous Operation (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Traits.md Demonstrates how to create a `Single` using the `.create` method. This example wraps an asynchronous `URLSession` data task, emitting a `.success` event with the parsed JSON or a `.failure` event on error. ```Swift func getRepo(_ repo: String) -> Single<[String: Any]> { return Single<[String: Any]>.create { single in let task = URLSession.shared.dataTask(with: URL(string: "https://api.github.com/repos/\(repo)")!) { data, _, error in if let error = error { single(.failure(error)) return } guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves), let result = json as? [String: Any] else { single(.failure(DataError.cantParseJSON)) return } single(.success(result)) } task.resume() return Disposables.create { task.cancel() } } } ``` -------------------------------- ### Implementing Custom Map Operator in RxSwift (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Demonstrates how to create a custom 'map' operator for 'ObservableType' using the 'Observable.create' method. It subscribes to the source observable, transforms each '.next' event's value, and emits the result, forwarding '.error' and '.completed' events. Requires RxSwift. ```Swift extension ObservableType { func myMap(transform: @escaping (Element) -> R) -> Observable { return Observable.create { observer in let subscription = self.subscribe { e in switch e { case .next(let value): let result = transform(value) observer.on(.next(result)) case .error(let error): observer.on(.error(error)) case .completed: observer.on(.completed) } } return subscription } } } ``` -------------------------------- ### Calculating Value Imperatively in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Examples.md Standard imperative Swift code demonstrating how a variable `c` is calculated once based on initial values of `a` and `b`. It shows that subsequent changes to `a` or `b` do not affect `c`. ```Swift // this is standard imperative code var c: String var a = 1 // this will only assign the value `1` to `a` once var b = 2 // this will only assign the value `2` to `b` once if a + b >= 0 { c = "\(a + b) is positive" // this will only assign the value to `c` once } ``` -------------------------------- ### Illustrating Imperative Side Effects in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Examples.md Follow-up to the imperative example, showing that changing the value of `a` after the initial calculation does not update `c`, highlighting the lack of reactivity in this approach. ```Swift a = 4 // `c` will still be equal to "3 is positive" which is not good // we want `c` to be equal to "6 is positive" since 4 + 2 = 6 ``` -------------------------------- ### Debugging Compile Errors - Add Return Type Annotations Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md To help the compiler resolve type issues, explicitly annotate the return types of closures within the chain. This clarifies the expected output type for each step, often pinpointing where the type mismatch occurs. ```swift images = word .filter { s -> Bool in s.containsString("important") } .flatMap { word -> Observable in return self.api.loadFlickrFeed("karate") .catchError { error -> Observable in return just(JSON(1)) } } ``` -------------------------------- ### Improved Search Query Binding with Error Handling and Sharing (RxSwift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Traits.md An improved version of the basic example that addresses the potential issues. It ensures results are observed on the main scheduler, handles errors gracefully by returning an empty array, and shares the network request side effect among all subscribers using `share(replay: 1)`. ```Swift let results = query.rx.text .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .flatMapLatest { query in fetchAutoCompleteItems(query) .observeOn(MainScheduler.instance) // results are returned on MainScheduler .catchErrorJustReturn([]) // in the worst case, errors are handled } .share(replay: 1) // HTTP requests are shared and results replayed // to all UI elements results .map { "\($0.count)" } .bind(to: resultCount.rx.text) .disposed(by: disposeBag) results .bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in cell.textLabel?.text = "\(result)" } .disposed(by: disposeBag) ``` -------------------------------- ### Using a Custom Map Operator with RxSwift (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows how to apply the custom 'myMap' operator to an observable sequence ('myInterval'). It transforms emitted integer values into strings and subscribes to print the results. Depends on the custom 'myMap' operator extension and a source observable like 'myInterval'. ```Swift let subscription = myInterval(.milliseconds(100)) .myMap { e in return "This is simply \(e)" } .subscribe(onNext: { n in print(n) }) ``` -------------------------------- ### Debugging Compile Errors in RxSwift - Initial Code Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md This snippet shows an initial RxSwift chain that might cause compile errors due to implicit type deduction. The compiler might struggle to infer the correct types, especially with operators like `flatMap` and `catchError`. ```swift images = word .filter { $0.containsString("important") } .flatMap { word in return self.api.loadFlickrFeed("karate") .catchError { error in return just(JSON(1)) } } ``` -------------------------------- ### Sharing Subscription with share(replay: 1) - RxSwift - Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/GettingStarted.md Shows how to use the `share(replay: 1)` operator in RxSwift to share the results of an observable sequence among multiple subscribers. This is particularly useful in the UI layer to avoid duplicate work (like HTTP requests) when binding the same data to different UI elements. It replays the last emitted element to new subscribers. ```Swift let searchResults = searchText .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .distinctUntilChanged() .flatMapLatest { query in API.getSearchResults(query) .retry(3) .startWith([]) // clears results on new search term .catchErrorJustReturn([]) } .share(replay: 1) // <- notice the `share` operator ``` -------------------------------- ### Switching Schedulers with observeOn in RxSwift Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Schedulers.md Demonstrates how to use the `observeOn` operator to change the scheduler on which subsequent operations in the observable sequence are performed. This example switches execution first to a background scheduler and then back to the main scheduler. ```swift sequence1 .observeOn(backgroundScheduler) .map { n in print("This is performed on the background scheduler") } .observeOn(MainScheduler.instance) .map { n in print("This is performed on the main scheduler") } ``` -------------------------------- ### Binding UI Text Field to Label with RxSwift in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Examples.md Shows how to bind the `rx.text` property of a `UITextField` to a `UILabel` using RxSwift. It includes mapping the text to an integer, performing an asynchronous prime check, flattening the observable with `concat`, and binding the final result string to the label. ```Swift let subscription/*: Disposable */ = primeTextField.rx.text.orEmpty // type is Observable .map { WolframAlphaIsPrime(Int($0) ?? 0) } // type is Observable> .concat() // type is Observable .map { "number \($0.n) is prime? \($0.isPrime)" } // type is Observable .bind(to: resultLabel.rx.text) // return Disposable that can be used to unbind everything // This will set `resultLabel.text` to "number 43 is prime? true" after // server call completes. You manually trigger a control event since those are // the UIKit events RxCocoa observes internally. primeTextField.text = "43" primeTextField.sendActions(for: .editingDidEnd) // ... // to unbind everything, just call subscription.dispose() ``` -------------------------------- ### Get First Element from BlockingObservable in Swift Source: https://github.com/reactivex/rxswift/blob/main/RxBlocking/README.md This extension method on BlockingObservable blocks the current thread until the observable sequence emits its first element, then returns it. It is intended solely for testing purposes. ```swift extension BlockingObservable { public func first() throws -> Element? {} } ``` -------------------------------- ### Creating a Custom Observable for URLSession Requests in RxSwift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Why.md Provides an example of creating a custom Observable for URLSession data tasks. It wraps the asynchronous dataTask completion handler, emitting .next with data and response on success, .error on failure, and .completed when the task finishes. It also provides a disposable that cancels the task. ```Swift extension Reactive where Base: URLSession { public func response(request: URLRequest) -> Observable<(Data, HTTPURLResponse)> { return Observable.create { observer in let task = self.base.dataTask(with: request) { (data, response, error) in guard let response = response, let data = data else { observer.on(.error(error ?? RxCocoaURLError.unknown)) return } guard let httpResponse = response as? HTTPURLResponse else { observer.on(.error(RxCocoaURLError.nonHTTPResponse(response: response))) return } observer.on(.next(data, httpResponse)) observer.on(.completed) } task.resume() return Disposables.create(with: task.cancel) } } } ``` -------------------------------- ### RxSwift Generated CombineLatest (Arity 2) Source: https://github.com/reactivex/rxswift/blob/main/Preprocessor/README.md This Swift code snippet is an example of the output generated by processing the `CombineLatest+arity.tt.swift` template. It shows the specific overloads for the `combineLatest` and `combineLatestOrDie` operators when handling exactly two input observables (arity 2). This generated code is included in the final RxSwift library. ```Swift // This file is autogenerated. // Take a look at `Preprocessor` target in RxSwift project // // CombineLatest.tt.swift // RxSwift // // Created by Krunoslav Zaher on 4/22/15. // Copyright (c) 2015 Krunoslav Zaher. All rights reserved. // import Foundation // 2 public func combineLatestOrDie (source1: Observable, source2: Observable, resultSelector: (E1, E2) -> Result) -> Observable { return CombineLatest2( source1: source1, source2: source2, resultSelector: resultSelector ) } public func combineLatest (source1: Observable, source2: Observable, resultSelector: (E1, E2) -> R) -> Observable { return CombineLatest2( source1: source1, source2: source2, resultSelector: { success(resultSelector($0, $1)) } ) } ``` -------------------------------- ### Building RxSwift as Static Library with Carthage (Bash) Source: https://github.com/reactivex/rxswift/blob/main/README.md This script provides a workaround to build RxSwift as a static library using Carthage. It first updates RxSwift without building, then uses `sed` to modify the project file to change the build type to `staticlib`, and finally builds RxSwift specifically for the iOS platform. ```Bash carthage update RxSwift --platform iOS --no-build sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj carthage build RxSwift --platform iOS ``` -------------------------------- ### Defining GitHub Search with RxSwift/RxCocoa (Swift) Source: https://github.com/reactivex/rxswift/blob/main/README.md This snippet demonstrates how to use RxCocoa's `rx.text` to observe search bar input, debounce it, filter duplicates, and then use `flatMapLatest` to perform a GitHub search based on the query, handling empty queries and errors. It uses `MainScheduler` for UI updates. ```Swift let searchResults = searchBar.rx.text.orEmpty .throttle(.milliseconds(300), scheduler: MainScheduler.instance) .distinctUntilChanged() .flatMapLatest { query -> Observable<[Repository]> in if query.isEmpty { return .just([]) } return searchGitHub(query) .catchAndReturn([]) } .observe(on: MainScheduler.instance) ``` -------------------------------- ### Build Swift Package Manager Project Source: https://github.com/reactivex/rxswift/blob/main/README.md Executes the Swift Package Manager build command to compile the project defined in Package.swift, resolving dependencies and creating build artifacts. ```Bash $ swift build ``` -------------------------------- ### Updating Carthage Dependencies (Bash) Source: https://github.com/reactivex/rxswift/blob/main/README.md This command updates the dependencies specified in the `Cartfile` using Carthage. It fetches and builds the specified frameworks, placing them in the `Carthage/Build` directory. ```Bash carthage update ``` -------------------------------- ### Running All Tests with Shell Script Source: https://github.com/reactivex/rxswift/blob/main/CONTRIBUTING.md Describes the command to execute the comprehensive test suite for the RxSwift project. This script must pass before submitting a pull request. ```Shell ./scripts/all-tests.sh ``` -------------------------------- ### Add RxSwift as Git Submodule Source: https://github.com/reactivex/rxswift/blob/main/README.md Adds the RxSwift repository as a git submodule to the current project, allowing manual integration and management of the dependency. ```Bash $ git submodule add git@github.com:ReactiveX/RxSwift.git ``` -------------------------------- ### Test Swift Package Manager Project with RxTest Source: https://github.com/reactivex/rxswift/blob/main/README.md Runs the Swift Package Manager test command. Setting the TEST environment variable enables testing modules that depend on RxTest. ```Bash $ TEST=1 swift test ``` -------------------------------- ### Chaining Rx Operations with flatMapLatest in Swift Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Tips.md Shows the preferred way to chain asynchronous operations in Rx using operators like `flatMapLatest`. This method simplifies disposable management and improves code readability compared to nested subscriptions. ```swift textField.rx.text .flatMapLatest { text in // Assuming this doesn't fail and returns result on main scheduler, // otherwise `catchError` and `observeOn(MainScheduler.instance)` can be used to // correct this. return performURLRequest(text) } ... .disposed(by: disposeBag) // only one top most disposable ``` -------------------------------- ### Exposing ControlEvent and ControlProperty Init (RxCocoa Swift) Source: https://github.com/reactivex/rxswift/blob/main/CHANGELOG.md The initializers for `ControlEvent` and `ControlProperty` are now exposed publicly. ```Swift ControlEvent ``` ```Swift ControlProperty ``` -------------------------------- ### Get Last Element from BlockingObservable in Swift Source: https://github.com/reactivex/rxswift/blob/main/RxBlocking/README.md This extension method on BlockingObservable blocks the current thread until the observable sequence completes, then returns the last element emitted. It is intended solely for testing purposes. ```swift extension BlockingObservable { public func last() throws -> Element? {} } ``` -------------------------------- ### Define RxSwift Dependency with Swift Package Manager Source: https://github.com/reactivex/rxswift/blob/main/README.md Creates a Package.swift file to define a Swift Package Manager package named 'RxProject' and adds RxSwift as a dependency, specifying the version constraint and linking RxCocoa. ```Swift // swift-tools-version:5.0 import PackageDescription let package = Package( name: "RxProject", dependencies: [ .package(url: "https://github.com/ReactiveX/RxSwift.git", .upToNextMajor(from: "6.0.0")) ], targets: [ .target(name: "RxProject", dependencies: ["RxSwift", .product(name: "RxCocoa", package: "RxSwift")]), ] ) ``` -------------------------------- ### Binding Combined Text Fields with RxSwift (Swift) Source: https://github.com/reactivex/rxswift/blob/main/Documentation/Why.md Demonstrates declarative data binding using RxSwift operators `combineLatest`, `map`, and `bind` to combine text from two text fields, format it, and display the result in a label. ```Swift Observable.combineLatest(firstName.rx.text, lastName.rx.text) { $0 + " " + $1 } .map { "Greetings, \($0)" } .bind(to: greetingLabel.rx.text) ```