ProductPromotion
Logo

Swift

made by https://0x3d.site

GitHub - GoodRequest/GoodReactor: ⚛️ GoodReactor is a Redux-inspired Reactor framework for iOS developed using Swift. It enables seamless communication between the View Model, View Controller, and Coordinator through state and navigation functions. It ensures no side-effects by interacting with dependencies outside of the Reduce function. Integrate it with using SPM!
⚛️ GoodReactor is a Redux-inspired Reactor framework for iOS developed using Swift. It enables seamless communication between the View Model, View Controller, and Coordinator through state and navi...
Visit Site

GitHub - GoodRequest/GoodReactor: ⚛️ GoodReactor is a Redux-inspired Reactor framework for iOS developed using Swift. It enables seamless communication between the View Model, View Controller, and Coordinator through state and navigation functions. It ensures no side-effects by interacting with dependencies outside of the Reduce function. Integrate it with using SPM!

GitHub - GoodRequest/GoodReactor: ⚛️ GoodReactor is a Redux-inspired Reactor framework for iOS developed using Swift. It enables seamless communication between the View Model, View Controller, and Coordinator through state and navigation functions. It ensures no side-effects by interacting with dependencies outside of the Reduce function. Integrate it with using SPM!

Logo

GoodReactor

Check out the Documentation

iOS Version Swift Version Supported devices Contains Test Dependency Manager

GoodReactor is an adaptation of the Reactor framework that is Redux inspired. The view model communicates with the view controller via the State and with the Coordinator via the navigation function. You communicate to the viewModel via Actions Viewmodel changes state in the Reduce function Viewmodel interactes with dependencies outside of the Reduce function not to create side-effects

Link to the original reactor kit: https://github.com/ReactorKit/ReactorKit

Installation

Swift Package Manager

Create a Package.swift file and add the package dependency into the dependencies list. Or to integrate without package.swift add it through the Xcode add package interface.

import PackageDescription

let package = Package(
    name: "SampleProject",
    dependencies: [
        .package(url: "https://github.com/GoodRequest/GoodReactor" .upToNextMajor("2.0.0"))
    ]
)

Usage

GoodReactor

ViewModel

In your ViewModel define Actions, Mutations, Destinations and the State

  • State defines all data of a View (or a ViewController)
  • Action represents user actions that are sent from the View.
  • Mutation represents state changes from external sources.
  • Destination represents all possible destinations, where user can navigate.
@Observable final class ViewModel: Reactor {
    enum Action {
        case login(username: String, password: String)
    }

    enum Mutation {
        case didReceiveAuthResponse(Credentials)
    }

    enum Destination {
        case homeScreen
        case errorAlert
    }

    @Observable final class State {
        var username: String
        var password: String
    }
}

You can provide the initial state of the view in the makeInitialState function.

func makeInitialState() -> State {
    return State()
}

Finally in the reduce function you define how state changes, according to certain events:

typealias Event = NewReactor.Event<Action, Mutation, Destination>

func reduce(state: inout State, event: Event) {
    switch event.kind {
    case .action(.login(...)):
        // ...

    case .mutation:
        // ...

    case .destination:
        // ...
    }
}

You can run asynchronous tasks by using run and returning the result in form of a Mutation.

func reduce(state: inout State, event: Event) {
    switch event.kind {
    case .action(.login(let username, let password)):
        run(event) {
            let credentials = await networking.login(username, password)
            return Mutation.didReceiveAuthResponse(credentials)
        }

    // ...

    case .mutation(.didReceiveAuthResponse(let credentials)):
        // proceed with login
    }
}

You can listen to external changes by subscribe-ing to event Publisher-s. You start the subscriptions by calling the start() function.

// in ViewModel:
func transform() {
    subscribe {
        await ExternalTimer.shared.timePublisher
    } map: {
        Mutation.didChangeTime(seconds: $0)
    }
}

// in View (SwiftUI):
var body: some View {
    MyContentView()
        .task { viewModel.start() }
}

View (SwiftUI)

You add the ViewModel as a property wrapper to your view:

@ViewModel private var model = MyViewModel()

To access the current State you use:

// read-only access
Text(model.username)

// binding (refactored to a variable for better readability)
let binding = model.bind(\.username, action: { .setUsername($0) })
TextField("Username",  text: binding)

To send an event to the ViewModel you call:

model.send(action: .login(username, password))
model.send(destination: .errorAlert)

UIViewController (UIKit/Combine)

From UIViewController (in UIKit, or any other frameworks) you can send actions to ViewModel via Combine:

myButton.publisher(for: .touchUpInside).map { _ in .login(username, password) }
    .map { .action($0) }
    .subscribe(model.eventStream)
    .store(in: &cancellables)

Then use Combine to subscribe to state changes, so every time the state is changed, ViewController can be updated as well:

reactor.stateStream
    .map { String($0.username) }
    .assign(to: \.text, on: usernameLabel, ownership: .weak)
    .store(in: &cancellables)

License

GoodReactor repository is released under the MIT license. See LICENSE for details.

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory