Action

repository·master·Indexed 21 days ago

https://github.com/rxswiftcommunity/action

A library for RxSwift that provides a high-level abstraction for managing asynchronous work. It handles execution state, prevents concurrent executions of the same task, and integrates with UIKit components such as UIButton and UIAlertAction.

Tokens
1.1K
Snippets
7
Records
7
Agent score
25%

What's inside Action

  1. What is an Action and how does it work?

    master

    An Action is an abstraction built on top of RxSwift that manages the execution of asynchronous work.

    An Action is initialized with a workFactory: a closure that accepts an input and returns an Observable. When execute() is called, the workFactory is invoked with the provided input, and the Action subscribes to the resulting observable.

    Key behaviors:

    • Single Execution: An action can only execute one task at a time. Attempting to execute an action that is already running will result in an error.
    • State Management: It tracks whether it is currently executing (via an executing property) and whether it is enabled.
    • Event Aggregation: It aggregates Next and Error events from all individual executions across its elements and errors properties.
    • Enabled State: An action can only be executed while it is "enabled". You can control this via the enabled property or by providing an enabledIf observable during initialization.
    action: Action<String, Bool> = Action(workFactory: { input in
        return networkLibrary.checkEmailExists(input)
    })
    
    // To run the work:
    action.execute("ash@ashfurrow.com")
  2. Install Action via Carthage

    master

    Add the following line to your Cartfile:

    gitub "RxSwiftCommunity/Action" ~> 5.0.0

    Note: If you are using RxSwift 3.2.0 or below, use Action ~> 2.2.0 instead.

    Then run:

    carthage update
    gitub "RxSwiftCommunity/Action" ~> 5.0.0
    carthage update
  3. Bind an Action to a UIButton

    master

    The library provides a UIButton extension that simplifies UI integration. By assigning an action to button.rx.action, the following happens automatically:

    • When the button is pressed, the action is executed.
    • The button's enabled state is automatically bound to the action's enabled property (e.g., the button disables itself while work is in progress or if enabledIf is false).

    For actions that do not require input, use CocoaAction (which is an alias for Action<Void, Void>). For complex tasks like file downloads that need to report progress, use a custom Action<Void, Int> instead.

    // For simple Void-to-Void actions
    button.rx.action = action
    
    // For actions with input, use bindTo with a closure to provide the input
    button1.rx.bindTo(action) { _ in return "Hello" }
  4. Use UIAlertAction.Action for alerts

    master

    There is an extension for UIAlertAction that allows you to use an Action within a UIAlertController. Because of UIAlertAction limitations, you must use the provided class method instead of a standard initializer.

    let action = UIAlertAction.Action("Hi", style: .default)
  5. Control execution with enabledIf

    master

    You can pass an enabledIf parameter to the Action initializer. This takes an Observable<Bool> that determines if the action is allowed to run. The action's actual enabled state is a combination of this signal and its current executing state.

    This is useful for binding form validation logic directly to the action's ability to execute.

    let validEmailAddress = emailTextField.rx.text.map(isValidEmail)
    
    action: Action<String, Bool> = Action(enabledIf: validEmailAddress, workFactory: { input in
        return networkLibrary.checkEmailExists(input)
    })
  6. Initialize an Action with input and output types

    master

    When creating an Action, you define two generic types:

    1. The Input type: The type of data passed into execute().
    2. The Output type: The type of elements emitted by the Observable returned by the workFactory.

    Example: Action<String, Bool> means the action takes a String as input and produces an observable that emits Bool values.

    action: Action<String, Bool> = Action(workFactory: { input in
        return networkLibrary.checkEmailExists(input)
    })