An array class implemented in Swift that can be observed using ReactiveCocoa's Signals

Overview

ReactiveArray

Carthage compatible Circle CI Build Status Coverage Status Release Join the chat at https://gitter.im/Wolox/ReactiveArray

An array class implemented in Swift that can be observed using ReactiveCocoa's Signals.

Installation

Carthage

Add the following to your Cartfile:

github "Wolox/ReactiveArray"

Then run carthage update.

Follow the current instructions in Carthage's README for up to date installation instructions.

You'll also need to add Result.framework, Box.framework and ReactiveCocoa.framework to your Xcode project.

Usage

Array operations

let array = ReactiveArray(elements: [1,2,3])

array.append(4) // => [1,2,3,4]
array.append(5) // => [1,2,3,4,5]

array[0] = 5 // => [5,2,3,4,5]
array.removeAtIndex(4) // => [5,2,3,4]

ReactiveArray conforms to CollectionType and MutableCollectionType which allows you to perform operations like map or filter.

Observing changes

The array can be observed for mutations using the signal or producer properties. Both Signal and SignalProducer will emit Operation values on observation for any of the mutating operations performed to the array.

Operation is an enumeration with four cases. One for each mutating operation: Append, Insert, Update and RemoveElement

Using SignalProducer

Prints an append operation for each element that has already been stored in the array and then the corresponding operation for any new operation performed to the array.

let array = ReactiveArray(elements: [1,2,3])
array.producer |> start(next: { println($0) })
array[0] = 5
array[1] = 4
array.append(2)
array.removeAtIndex(2)

will print the following output:

.Append(value: 1)
.Append(value: 2)
.Append(value: 3)
.Update(value: 5, atIndex: 0)
.Update(value: 4, atIndex: 1)
.RemoveElement(atIndex:2)

Using Signal

The signal property will only emit values for operations performed in the array after observation.

let array = ReactiveArray(elements: [1,2,3])
array.signal.observe { println($0) }
array[0] = 5
array[1] = 4
array.append(2)
array.removeAtIndex(2)

will print the following output:

.Update(value: 5, atIndex: 0)
.Update(value: 4, atIndex: 1)
.RemoveElement(atIndex:2)

Using observableCount

You can also observe the observableCount property that exposes a producer that emits the current amount of elements each time the array is mutated.

let array = ReactiveArray<String>()
array.observableCount.producer |> start(next: { println($0) })
array.append("Hello")
array.append("World")

will print the following output:

0
1
2

Mirror

Mirror creates a new ReactiveArray by applying a transform operation for each element contained in the original array. It is like map but the returned array will mutate everytime the original array mutates.

let array = ReactiveArray(elements: [1,2,3])
let doubles = array.mirror { $0 * 2 }
doubles.producer |> start(next: { println($0) })
array.append(4)
array.append(5)
array[0] = 6

will print the following output:

.Append(value: 2)
.Append(value: 4)
.Append(value: 6)
.Append(value: 8)
.Append(value: 10)
.Update(value: 12, atIndex: 0)

Contributing

Setup project

If you want to contribute you need to setup your development environment first.

git clone https://github.com/Wolox/ReactiveArray.git
cd ReactiveArray
script/bootstrap
open ReactiveArray.xcodeproj

Environment dependencies

The following dependencies must be installed in your development machine.

  • XCode & XCode command line tools
  • Homebrew
  • Ruby
  • Bundler (sudoless)
  • Carthage
  • Gcovr
  • SwiftCov

About

This project is maintained by Guido Marucci Blas and it was written by Wolox.

Wolox

License

ReactiveArray is available under the MIT license.

Copyright (c) 2015 Guido Marucci Blas <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Comments
  • Minimum deployment target iOS 8.3

    Minimum deployment target iOS 8.3

    First of all, awesome piece of code!

    I checked and it seems like there is nothing specific to iOS 8.3 and up that this library needs. Can we lower the minimum deployment target to iOS 8.0 instead?

    opened by jmper1 2
  • Fix observable count bug on insert

    Fix observable count bug on insert

    This fixes a bug that causes a ReactiveArray instance to not send observable count events when a new element is inserted into it. Got confused at first since the unit test cases seemed to agree with the code. I've updated the unit test as well to reflect the fix.

    opened by jmper1 1
  • observableCount should not start with a count of 0.

    observableCount should not start with a count of 0.

    If you implement the observableCount like so private lazy var _mutableCount: MutableProperty<Int> = MutableProperty<Int>(self._elements.count). Then the count won't start with 0!

    opened by taonos 1
  • Refactor project structure to use workspace

    Refactor project structure to use workspace

    We should use workspace in the same way described in this answer http://www.quora.com/How-should-an-OSS-library-be-structured-for-distribution-with-both-Carthage-and-CocoaPods

    Also remember to add depencies like is described in the answer of this post http://stackoverflow.com/questions/10264440/target-dependency-between-two-projects-in-the-same-workspace

    opened by guidomb 1
  • Adds Cocoapod support

    Adds Cocoapod support

    This is a work-in-progress and needs to be fixed because bundle exec pod lib lint exits with error.

     -> ReactiveArray (0.1.0)
        - ERROR | [OSX] Returned an unsuccessful exit code. You can use `--verbose` for more information.
        - ERROR |  /Users/guidomb/Documents/projects/wolox/ReactiveArray/ReactiveArray/ReactiveArray.swift:20:8: error: no such module 'ReactiveCocoa'
    
    [!] ReactiveArray did not pass validation.
    You can use the `--no-clean` option to inspect any issue.
    
    enhancement help wanted 
    opened by guidomb 1
  • Add a Gitter chat badge to README.md

    Add a Gitter chat badge to README.md

    Wolox/ReactiveArray now has a Chat Room on Gitter

    @guidomb has just created a chat room. You can visit it here: https://gitter.im/Wolox/ReactiveArray.

    This pull-request adds this badge to your README.md:

    Gitter

    If my aim is a little off, please let me know.

    Happy chatting.

    PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.

    opened by gitter-badger 0
  • Bump tzinfo from 1.2.2 to 2.0.5

    Bump tzinfo from 1.2.2 to 2.0.5

    Bumps tzinfo from 1.2.2 to 2.0.5.

    Release notes

    Sourced from tzinfo's releases.

    v2.0.5

    • Changed DateTime results to always use the proleptic Gregorian calendar. This affects DateTime results prior to 1582-10-15 and any arithmetic performed on the results that would produce a secondary result prior to 1582-10-15.
    • Added support for eager loading all the time zone and country data by calling either TZInfo::DataSource#eager_load! or TZInfo.eager_load!. Compatible with Ruby On Rails' eager_load_namespaces. #129.
    • Ignore the SECURITY file from Arch Linux's tzdata package. #134.

    TZInfo v2.0.5 on RubyGems.org

    v2.0.4

    • Fixed an incorrect InvalidTimezoneIdentifier exception raised when loading a zoneinfo file that includes rules specifying an additional transition to the final defined offset (for example, Africa/Casablanca in version 2018e of the Time Zone Database). #123.

    TZInfo v2.0.4 on RubyGems.org

    v2.0.3

    • Added support for handling "slim" format zoneinfo files that are produced by default by zic version 2020b and later. The POSIX-style TZ string is now used calculate DST transition times after the final defined transition in the file. #120.
    • Fixed TimeWithOffset#getlocal returning a TimeWithOffset with the timezone_offset still assigned when called with an offset argument on JRuby 9.3.
    • Rubinius is no longer supported.

    TZInfo v2.0.3 on RubyGems.org

    v2.0.2

    • Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
    • Fixed warnings when running on Ruby 2.8. #113.

    TZInfo v2.0.2 on RubyGems.org

    v2.0.1

    • Fixed "SecurityError: Insecure operation - require" exceptions when loading data with recent Ruby releases in safe mode. #100.
    • Fixed warnings when running on Ruby 2.7. #109.
    • Added a TZInfo::Timezone#=~ method that performs a regex match on the time zone identifier. #99.
    • Added a TZInfo::Country#=~ method that performs a regex match on the country code.

    TZInfo v2.0.1 on RubyGems.org

    v2.0.0

    Added

    • to_local and period_for instance methods have been added to TZInfo::Timezone. These are similar to utc_to_local and period_for_utc, but take the UTC offset of the given time into account.
    • abbreviation, dst?, base_utc_offset and observed_utc_offset instance methods have been added to TZInfo::Timezone, returning the abbreviation, whether daylight savings time is in effect and the UTC offset of the time zone at a specified time.
    • A TZInfo::Timestamp class has been added. It can be used with TZInfo::Timezone in place of a Time or DateTime.
    • local_time, local_datetime and local_timestamp instance methods have been added to TZInfo::Timezone. These methods construct local Time, DateTime and TZInfo::Timestamp instances with the correct UTC offset and abbreviation for the time zone.
    • Support for a (yet to be released) version 2 of tzinfo-data has been added, in addition to support for version 1. The new version will remove the (no longer needed) DateTime parameters from transition times, reduce memory consumption and improve the efficiency of loading timezone and country indexes.
    • A TZInfo::VERSION constant has been added, indicating the TZInfo version number.

    Changed

    • The minimum supported Ruby versions are now Ruby MRI 1.9.3, JRuby 1.7 (in 1.9 or later mode) and Rubinius 3.
    • Local times are now returned using the correct UTC offset (instead of using UTC). #49 and #52.
    • Local times are returned as instances of TimeWithOffset, DateTimeWithOffset or TZInfo::TimestampWithOffset. These classes subclass Time, DateTime and TZInfo::Timestamp respectively. They override the default behaviour of the base classes to return information about the observed offset at the indicated time. For example, the zone abbreviation is returned when using the %Z directive with strftime.
    • The transitions_up_to, offsets_up_to and strftime instance methods of TZInfo::Timezone now take the UTC offsets of given times into account (instead of ignoring them as was previously the case).
    • The TZInfo::TimezonePeriod class has been split into two subclasses: TZInfo::OffsetTimezonePeriod and TZInfo::TransitionsTimezonePeriod. TZInfo::OffsetTimezonePeriod is returned for time zones that only have a single offset. TZInfo::TransitionsTimezonePeriod is returned for periods that start or end with a transition.

    ... (truncated)

    Changelog

    Sourced from tzinfo's changelog.

    Version 2.0.5 - 19-Jul-2022

    • Changed DateTime results to always use the proleptic Gregorian calendar. This affects DateTime results prior to 1582-10-15 and any arithmetic performed on the results that would produce a secondary result prior to 1582-10-15.
    • Added support for eager loading all the time zone and country data by calling either TZInfo::DataSource#eager_load! or TZInfo.eager_load!. Compatible with Ruby On Rails' eager_load_namespaces. #129.
    • Ignore the SECURITY file from Arch Linux's tzdata package. #134.

    Version 2.0.4 - 16-Dec-2020

    • Fixed an incorrect InvalidTimezoneIdentifier exception raised when loading a zoneinfo file that includes rules specifying an additional transition to the final defined offset (for example, Africa/Casablanca in version 2018e of the Time Zone Database). #123.

    Version 2.0.3 - 8-Nov-2020

    • Added support for handling "slim" format zoneinfo files that are produced by default by zic version 2020b and later. The POSIX-style TZ string is now used calculate DST transition times after the final defined transition in the file. #120.
    • Fixed TimeWithOffset#getlocal returning a TimeWithOffset with the timezone_offset still assigned when called with an offset argument on JRuby 9.3.
    • Rubinius is no longer supported.

    Version 2.0.2 - 2-Apr-2020

    • Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
    • Fixed warnings when running on Ruby 2.8. #113.

    Version 2.0.1 - 24-Dec-2019

    • Fixed "SecurityError: Insecure operation - require" exceptions when loading data with recent Ruby releases in safe mode. #100.
    • Fixed warnings when running on Ruby 2.7. #109.
    • Added a TZInfo::Timezone#=~ method that performs a regex match on the time zone identifier. #99.
    • Added a TZInfo::Country#=~ method that performs a regex match on the country code.

    Version 2.0.0 - 26-Dec-2018

    ... (truncated)

    Commits
    • d9b289e Preparing v2.0.5.
    • 264c763 Add v0.3.61 and v1.2.10 from the 0.3 and 1.2 branches.
    • ca29f34 Fix relative path loading tests.
    • c4f177c Add a top level eager_load! method for Rails compatibility.
    • 94be919 Support preloading all data from a DataSource.
    • fe7ad26 Clarify that both files and directories are excluded.
    • d2883cf Tidy up of security file ignoring.
    • 6a4766e Merge pull request #133.
    • 5d53b59 Workaround for 'Permission denied - NUL' errors with JRuby on Windows.
    • 83450a1 ignore SECURITY file for Arch tzdata package
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump i18n from 0.7.0 to 1.10.0

    Bump i18n from 0.7.0 to 1.10.0

    Bumps i18n from 0.7.0 to 1.10.0.

    Release notes

    Sourced from i18n's releases.

    v1.10.0

    What's Changed

    New Features

    Bug fixes

    Other changes

    New Contributors

    Full Changelog: https://github.com/ruby-i18n/i18n/compare/v1.9.1...v1.10.0

    v1.9.1

    What's Changed

    Full Changelog: https://github.com/ruby-i18n/i18n/compare/v1.9.0...v1.9.1

    v1.9.0

    Minor version bump: The number of changes in this release are more than I would feel comfortable including in a point release. Therefore, I have bumped the minor version number here. -- @​radar

    What's Changed

    ... (truncated)

    Commits
    • b805537 Bump to 1.10.0
    • 789d12e Merge pull request #622 from movermeyer/movermeyer/resolve_defaults_with_curr...
    • 19f190d Allow overriding of entry resolving entry resolving separate from defaults
    • 0a9e47a Merge pull request #621 from mishina2228/add-badge
    • 0820914 Add a version badge
    • fb7095a Merge pull request #612 from Shopify/pm/lazy-loadable-backend
    • 422959a Introduce LazyLoadable backend
    • 00fc810 Merge pull request #616 from codealchemy/normalize-keys/splat
    • f3c1936 Tweak array construction in normalize_keys
    • eb9dbf4 Yield loaded translations to block in #load_translations
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Update ReactiveCocoa to 4.1.0 & fix xcodeproj settings

    Update ReactiveCocoa to 4.1.0 & fix xcodeproj settings

    Hi. I found your code very useful, and added a fun ReactiveArray UI example in https://github.com/inamiy/ReactiveCocoaCatalog/pull/4 you might be interested :wink:

    There were some fixes & improvements needed for integration as follows:

    • ReactiveCocoa 4.1.0 & Result 2.0.0 for Swift 2.2 support
    • Remove unnecessary carthage copy-frameworks (this is only for app binary)
    • Change ENABLE_BITCODE = Default (YES)
    • Conform ReactiveArray to ArrayLiteralConvertible & Equatable

    Sorry for bulk fixes, but I think they are all needed, so hopefully you will merge this!

    opened by inamiy 0
  • dispose of producer in deinit

    dispose of producer in deinit

    This fixes a crash where if the ReactiveArray was initialized with a producer and the producer sends a value after the ReactiveArray has been dealloced, the app will crash on calling a method on unowned dealloced self in _signal.observe.

    Easiest way to reproduce this bug is using a mirror:

    let xs = ReactiveArray<String>()
    ;{
    let ys = xs.mirror { _ in "I will crash" }
    }()
    xs.append("ys shall crash now!")
    

    There may be better ways to fix this than my solution, so feel free to implement your own. I would have liked to use .takeUntil(willDeallocSignal) instead of the disposeBag, but I dont have a willDeallocSignal for arbitrary swift classes (not NSObject) I could tackle this by disposing of the _signal.observe to prevent other possible problems of this kind, but I felt like my change fixes this particular problem as locally as possible.

    opened by pteasima 0
  • Added old value to .RemoveElement operation

    Added old value to .RemoveElement operation

    Hi,

    as discussed in #21, I'm creating PR now.

    I've updated some more stuff, like Operation.RemoveElement now returns a value and is mappable so I've updated tests as well. Please revise them as it's not my cup of tea.

    opened by olejnjak 2
  • Add old values to Update and Remove operations

    Add old values to Update and Remove operations

    Hi,

    I'd like to open a discussion whether it would be useful to add oldValue parameters to Update and Remove operations or I'm just missing something useful?

    E.g. my current use case is this: I'm using ReactiveArray to manage annotations displayed in MKMapView. On my viewModel I have an array which changes based on items that came from API. So in cases when the array changes I'd like to update/remove appropriate annotations which currently seems to be impossible or complicated.

    I think that adding a simple argument oldValue to those operations wouldn't be that complicated and would solve those cases effectively.

    Other opinions? :-)

    opened by olejnjak 3
Releases(v0.7.0)
Owner
Wolox
We are a tech company specialized in end-to-end development of high impact products.
Wolox
📬 A lightweight implementation of an observable sequence that you can subscribe to.

Features Lightweight Observable is a simple implementation of an observable sequence that you can subscribe to. The framework is designed to be minima

Felix M. 133 Aug 17, 2022
Store-App - Store app made for IOS using Swift programming language

Store-App Store app views products, cart, and using login from https://fakestore

Anas Khalil 2 Jan 1, 2022
Implementation of the repository pattern in Swift, using generics.

Store Simple, powerful and elegant implementation of the repository pattern, using generics. Why? ?? There are a couple of ways to implement the Repos

Narek Mailian 2 Aug 31, 2022
Binding - Data binding framework (view model binding on MVVM) written using propertyWrapper and resultBuilder

Binding Data binding framework (view model binding on MVVM) written using @prope

Sugeng Wibowo 4 Mar 23, 2022
This is the demo of MVVM-C structure with dependency injection using RxSwift.

MVVMC-Demo Demo defination This is the demo project, I have integrated two APIs for MovieDB APIS (https://www.themoviedb.org/). One for the listing of

Anshul Shah 61 Dec 6, 2022
A Simple exemple of a launching screen made of 100% using SwuiftUI.

A Simple exemple of a launching screen made of 100% using SwuiftUI. You can modify and use it in your app Compatible from iOS 14 (older not tested ) to iOS 16 (beta tested only )

Maxime 2 Nov 4, 2022
Redux for Swift - a predictable state container for Swift apps

Merge / deprecation announcement: ReduxKit and Swift-Flow have joined forces! The result is ReSwift. The nitty gritty: We decided to deprecate ReduxKi

null 613 Jan 3, 2023
Reactive Programming in Swift

Rx is a generic abstraction of computation expressed through Observable<Element> interface, which lets you broadcast and subscribe to values and other

ReactiveX 23.1k Jan 5, 2023
RxSwift extentions for Swift optionals and "Occupiable" types

RxOptional RxSwift extentions for Swift optionals and "Occupiable" types. Usage All operators are available on Driver as well unless otherwise marked.

Thane Gill 8 Jun 28, 2020
Unidirectional Data Flow in Swift - Inspired by Redux

ReSwift Supported Swift Versions: Swift 4.2, 5.x For Swift 3.2 or 4.0 Support use Release 5.0.0 or earlier. For Swift 2.2 Support use Release 2.0.0 or

null 7.3k Dec 25, 2022
A Swift Reactive Programming Kit

ReactiveKit is a lightweight Swift framework for reactive and functional reactive programming that enables you to get into the reactive world today. T

Declarative Hub 1.2k Dec 29, 2022
RxSwift wrapper around the elegant HTTP networking in Swift Alamofire

RxAlamofire RxAlamofire is a RxSwift wrapper around the elegant HTTP networking in Swift Alamofire. Getting Started Wrapping RxSwift around Alamofire

RxSwift Community 1.6k Jan 3, 2023
Simple and lightweight Functional Reactive Coding in Swift for the rest of us

The simplest Observable<T> implementation for Functional Reactive Programming you will ever find. This library does not use the term FRP (Functional R

Jens Ravens 1.1k Jan 3, 2023
Predictable state container for Swift too

ReduxSwift ReduxSwift is a minimal Swift port of Redux, a popular JavaScript library for application state management. Functionality Centralized State

Lucas Sunsi Abreu 38 Oct 6, 2020
Aftermath is a stateless message-driven micro-framework in Swift

Aftermath is a stateless message-driven micro-framework in Swift, which is based on the concept of the unidirectional data flow architecture.

HyperRedink 70 Dec 24, 2021
🔄 Unidirectional data flow in Swift.

Reactor Reactor is a framework for making more reactive applications inspired by Elm, Redux, and recent work on ReSwift. It's small and simple (just o

Reactor 175 Jul 9, 2022
An observables framework for Swift

?? snail A lightweight observables framework, also available in Kotlin Installation Carthage You can install Carthage with Homebrew using the followin

Compass 179 Nov 21, 2022
Lightweight observations and bindings in Swift

What is Hanson? Hanson is a simple, lightweight library to observe and bind values in Swift. It's been developed to support the MVVM architecture in o

Blendle 526 Oct 18, 2022
The easiest way to observe values in Swift.

Observable is the easiest way to observe values in Swift. How to Create an Observable and MutableObservable Using MutableObservable you can create and

Robert-Hein Hooijmans 368 Nov 9, 2022