Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nalexn/minimalist
Observable Property and Signal for building data-driven UI without Rx
https://github.com/nalexn/minimalist
combine-framework data-driven observer observer-pattern property-wrappers reactive reactiveswift redux rx rxswift signal
Last synced: 10 days ago
JSON representation
Observable Property and Signal for building data-driven UI without Rx
- Host: GitHub
- URL: https://github.com/nalexn/minimalist
- Owner: nalexn
- License: mit
- Created: 2020-05-31T10:09:29.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-04-12T05:41:25.000Z (over 1 year ago)
- Last Synced: 2024-03-15T00:46:50.332Z (8 months ago)
- Topics: combine-framework, data-driven, observer, observer-pattern, property-wrappers, reactive, reactiveswift, redux, rx, rxswift, signal
- Language: Swift
- Homepage:
- Size: 32.2 KB
- Stars: 93
- Watchers: 6
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Minimalist
[![Build Status](https://travis-ci.com/nalexn/Minimalist.svg?branch=master)](https://travis-ci.com/nalexn/Minimalist) [![Coverage Status](https://coveralls.io/repos/github/nalexn/minimalist/badge.svg)](https://coveralls.io/github/nalexn/minimalist)
Building data-driven UI without `Rx`
---
I'm a big fan of reactive frameworks. I've used RxSwift, ReactiveSwift, Combine, and I suffer every time I join the project where the team cannot adopt one for some reason.
* Problem #1: Teams beware the complexity and steep learning curve
* Problem #2: Traditional frameworks are too bulky for small projectsThis library is a take on cutting off everything non-essential. In fact, all you need to build the data-driven UI is **observable property** and **event broadcaster**. And that's all that you get with this micro-framework (just 100 lines of code):
### @Property
Also known as:
* `BehaviorRelay` in RxSwift
* `MutableProperty` in ReactiveSwift
* `CurrentValueSubject` in Combine```swift
class ViewModel {
@Property var items: [Items] = []
}// Access the current value:
viewModel.items.count// Subscribe on changes of the value:
viewModel.$items.observe(with: self) { (obj, items) in
...
}
```### @Signal
Also known as:
* `PublishRelay` in RxSwift
* `Signal` in ReactiveSwift
* `PassthroughSubject` in Combine```swift
class ViewModel {
@Signal var didReceiveMessage: Accepts
}// Broadcast a notification:
didReceiveMessage.send(message)// Subscribe on updates:
viewModel.$didReceiveMessage.observe(with: self) { (obj, message) in
...
}
```## Features
### Access control
You can restrict the write access from outside of the module using just Swift's access control:
```swift
class ViewModel {
@Property private(set) var value: String = "Minimalist"
@Signal private(set) var signal: Accepts
}// Cannot change property or trigger a signal:
viewModel.value = "abc" // ❌
viewModel.signal.send(()) // ❌
```### Automatic memory management
Subscription is bound to the lifetime of the supplied object and gets detached automatically. That object is also provided in the callback along with the value, so you don't need to do the `[weak self]` dance all the time:
```swift
class ViewController: UIViewController {
var tableView: UITableView
func viewDidLoad() {
...
viewModel.$items.observe(with: self) { (vc, items) in
vc.tableView.reloadData()
}
}
}
```### Filter state updates (Redux)
Data-driven UI works best with unidirectional data flow design, which may involve using a centralized state in the app.
Upon subscription, you can specify the `KeyPath` to the value inside the state container to receive scoped and filtered updates (like with `distinctUntilChanged`):
```swift
$appState.observe(\.screens.loginScreen, with: self) { (obj, state) in
...
}
```Pro Tip: `\.self` is also a valid `KeyPath`. This way you can discard the same values while observing a primitive type.
### Installation
@ Carthage
```
github "nalexn/minimalist"
```@ CocoaPods
```
pod 'Minimalist'
```@ SPM
```
.package(url: "https://github.com/nalexn/minimalist.git", from: "1.0.0")
```---
[![blog](https://img.shields.io/badge/blog-github-blue)](https://nalexn.github.io/?utm_source=nalexn_github) [![venmo](https://img.shields.io/badge/%F0%9F%8D%BA-Venmo-brightgreen)](https://venmo.com/nallexn)