Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/RxSwiftCommunity/Action
Abstracts actions to be performed in RxSwift.
https://github.com/RxSwiftCommunity/Action
hacktoberfest reactive-extensions rxswift
Last synced: 3 months ago
JSON representation
Abstracts actions to be performed in RxSwift.
- Host: GitHub
- URL: https://github.com/RxSwiftCommunity/Action
- Owner: RxSwiftCommunity
- License: mit
- Created: 2015-11-17T23:42:31.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2023-10-17T20:06:12.000Z (about 1 year ago)
- Last Synced: 2024-07-16T20:07:06.161Z (4 months ago)
- Topics: hacktoberfest, reactive-extensions, rxswift
- Language: Swift
- Homepage:
- Size: 877 KB
- Stars: 874
- Watchers: 32
- Forks: 150
- Open Issues: 25
-
Metadata Files:
- Readme: Readme.md
- Changelog: Changelog.md
- License: License.md
Awesome Lists containing this project
- awesome-rxswift - Action
- awesome-ios-1 - RxSwiftCommunity / Action
README
[![CI](https://github.com/RxSwiftCommunity/Action/actions/workflows/ci.yml/badge.svg)](https://github.com/RxSwiftCommunity/Action/actions/workflows/ci.yml)
Action
======This library is used with [RxSwift](https://github.com/ReactiveX/RxSwift) to provide an abstraction on top of observables: actions.
An action is a way to say "hey, later I'll need you to subscribe to this thing." It's actually a lot more involved than that.
Actions accept a `workFactory`: a closure that takes some input and produces an observable. When `execute()` is called on the action, the `workFactory` gets passed this parameter and the action subscribes to the observable that gets returned.
An action:
- Can only be executed while "enabled" (`true` if unspecified).
- Only executes one thing at a time.
- Aggregates next/error events across individual executions.Oh, and it has this really Swift thing with `UIButton` that's pretty cool. It'll manage the button's enabled state, make sure the button is disabled while your work is being done, all that stuff 👍
Usage
-----You have to pass a `workFactory` that takes input and returns an `Observable`. This represents some work that needs to be accomplished. Whenever you call `execute()`, you pass in input that's fed to the work factory. The `Action` will subscribe to the observable and emit the `Next` events on its `elements` property. If the observable errors, the error is sent as a `Next` even on the `errors` property. Neat.
Actions can only execute one thing at a time. If you try to execute an action that's currently executing, you'll get an error. The `executing` property sends `true` and `false` values as `Next` events.
```swift
action: Action = Action(workFactory: { input in
return networkLibrary.checkEmailExists(input)
})...
action.execute("[email protected]")
```Notice that the first generic parameter is the type of the input, and the second is the type of observable that `workFactory` creates. You can think of it a bit like the action's "output."
You can also specify an `enabledIf` parameter to the `Action` initializer.
```swift
let validEmailAddress = emailTextField.rx.text.map(isValidEmail)action: Action = Action(enabledIf: validEmailAddress, workFactory: { input in
return networkLibrary.checkEmailExists(input)
})
```Now `execute()` only does the work if the email address is valid. Super cool!
(Note that `enabledIf` isn't the same as the `enabled` property. You pass in `enabledIf` and the action uses that (combined with its current executing state) to determine if it's currently enabled.)
What's _really_ cool is the `UIButton` extension. It accepts a `CocoaAction`, which is just `Action`.
```swift
button.rx.action = action
```Now when the button is pressed, the action is executed. The button's `enabled` state is bound to the action's `enabled` property. That means you can feed your form-validation logic into the action as a signal, and your button's enabled state is handled for you. Also, the user can't press the button again before the action is done executing, since it only handles one thing at a time. Cool. Check out [this code example of CocoaAction _in_ action](https://github.com/artsy/eidolon/blob/cb31168fa29dcc7815fd4a2e30e7c000bd1820ce/Kiosk/Bid%20Fulfillment/GenericFormValidationViewModel.swift).
If you'd like to use `Action` to do a complex operation such as file download with download progress report (to update progress bar in the UI for example) you'd use `Action` instead of `CocoaAction`. Out of the box `CocoaAction` can't emit progress values, your own `Action` will do that. For details refer to [this article](http://www.sm-cloud.com/rxswift-action/).
If your scenario involves many buttons that needs to trigger the same `Action` providing different input, you can use `bindTo` on each `UIButton` with a closure that returns correct input.
```swift
let button1 = UIButton()
let button2 = UIButton()let action = Action { input in
print(input)
return .just(input)
}
button1.rx.bindTo(action) { _ in return "Hello"}
button2.rx.bindTo(action) { _ in return "Goodbye"}
````button1` and `button2` are sharing the same `Action`, but they are feeding it with different input (`Hello` and `Goodbye` that will be printed for corresponding tap).
A more complex use case can be a single action related to a `UIViewController` that manages your navigation, error handling and loading state. With this approach, you can have as many `UIButton`s (or `UIBarButtonItem`s) as you want and subscribe to `executing`, `errors`, `elements` and `completions` once and in a single common place.
There's also a really cool extension on `UIAlertAction`, used by [`UIAlertController`](http://ashfurrow.com/blog/uialertviewcontroller-example/). One catch: because of the limitations of that class, you can't instantiate it with the normal initializer. Instead, call this class method:
```swift
let action = UIAlertAction.Action("Hi", style: .default)
```Installing
----------### CocoaPods
Just add the line below to your Podfile:
```ruby
pod 'Action'
```Then run `pod install` and that'll be 👌
### Carthage
Add this to `Cartfile`
```
github "RxSwiftCommunity/Action" ~> 5.0.0
```If you are using RxSwift 3.2.0 or below, Use Action `~2.2.0` instead!
then run
```sh
> carthage update
```Thanks
------This library is (pretty obviously) inspired by [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa)'s [`Action` class](https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/ReactiveCocoa/Swift/Action.swift). Those developers deserve a lot of thanks!
License
-------MIT obvs.
![Permissive licenses are the only licenses permitted in the Q continuum.](https://38.media.tumblr.com/4ca19ffae09cb09520cbb5611f0a17e9/tumblr_n13vc9nm1Q1svlvsyo6_250.gif)