Code Monkey home page Code Monkey logo

Comments (22)

Qata avatar Qata commented on May 30, 2024 8

I've rewritten part of ReSwift to accept any FRP library, needing only a small amount of boilerplate for conforming to protocols. I removed all of the delegate style subscription code and added a default FRP observable into ReSwift as ObservableType as well, which is only very basic and gives roughly the same amount of functionality as newState(_:) did.

https://github.com/Qata/ReSwift

Counter example with ReactiveSwift and ReactiveCocoa:
https://github.com/Qata/SwiftFoldExample

from reswift.

Qata avatar Qata commented on May 30, 2024 4

After some feedback from @agentk I've changed my implementation to add new types instead of altering existing ones.

from reswift.

Odrakir avatar Odrakir commented on May 30, 2024 2

Actually I'm taking it further. My goal is to use the redux style architecture with Rx for inputs and outputs. This is a proof of concept of something I'm working on, I'll probably release an article and some cleaner code soon: https://github.com/Odrakir/CachopoDemo

from reswift.

Odrakir avatar Odrakir commented on May 30, 2024 1

Hi,

I'm trying out ReSwift and mixing it with RxSwift so it fits with my current UI implementation.

Working from @Ben-G's proposal I came up with this: https://gist.github.com/Odrakir/abf64b0712ec7348e30d960d22960830

In this case I pass a closure to the state method so I can map the main state to a substate. Also, as I made states Equatable, I can get updates only when that substate actually changes.

What do you think? Does it make sense?

from reswift.

r0nn avatar r0nn commented on May 30, 2024 1

Hi,

I am trying to implement Netflix's redux-observable "Epics", mentioned by @Odrakir @erneestoc :
https://gist.github.com/r0nn/be7f29b91674bf54b5307c2ccf6efd83

Usage:

let incEpic: Epic = { actionSubject, getState in
    return actionSubject
        .filter{ $0 is CounterActionIncrease }
        .debounce(0.2, scheduler: MainScheduler.instance)
        .map{ _ in CounterActionDecrease() }
}

let epicMiddleware = EpicMiddleware(epic: incEpic)

let mainStore = Store<AppState>(
    reducer: AppReducer(),
    state: nil,
    middleware: [epicMiddleware.createMiddleware()]
)

Have tried in Counter example, looks not bad.

from reswift.

DivineDominion avatar DivineDominion commented on May 30, 2024 1

@r0nn: Indeed looking slick! But would you have to create an epic as middleware for every event handler that results in an action dispatch like that? 🤔

@grundmanise: I use RxSwift mostly inside the UI layer, that is I subscribe to text field changes etc. In the end I reach the outer border of the UI layer in a service that subscribes to the UI events and dispatches actions to a store. You can populate the UI from ReSwift states with the convenience of libraries like "RxReSwift" and similar; then you can have Rx observables as store subscribers.

But even intermediary states go into the ReSwift state -- if they affect the program flow and are more than locally computed properties.

I like James K. Nelson: "The 5 Types Of React Application State" (August 29, 2016) http://jamesknelson.com/5-types-react-application-state/:

  1. Data
  2. Communication: pending requests; file operation queue
  3. Control State: view-specific state
  4. Session State: user information, settings
  5. Location State: navigation state; part of the URL in web apps; ReSwift-Router's current route's attached data

If anything that happens in my UI qualifies as communication state (outgoing: "user wants to delete the selected file") or control state (incoming: "show this image here"), it becomes part of the state managed by ReSwift.

That's just a heuristic I'm rolling with at the moment. It's not The Truth™ (yet :)) and you might come up with something cooler.

from reswift.

mosamer avatar mosamer commented on May 30, 2024

I'm still exploring the framework but why Rxing the subscriber? not the store itself. Something like that may be:
https://gist.github.com/mosamer/824067f387f66b92c244

I'm exposing an Observable for interested entities (probably views) to subscribe to it. May be add some slicers (duals to reducers) to slice out the unneeded chunks of the app state. What do you think?

from reswift.

Ben-G avatar Ben-G commented on May 30, 2024

@mosamer When I first tested Rx integration I went with this approach as well. However, I was always planning on making MainStore a final class, once I came up with another implementation.

Relying on subclassing for adding functionality to MainStore is not ideal, since it will always only allow us to use one specific type of store. E.g. currently Swift Flow Recorder is also implemented as a MainStore subclass; which was a temporary solution that I would like to change moving forward.

What if you want a recording store that also supports exposing an Rx state? That wouldn't be possible if both functionalities are provided as subclasses of MainStore.

This is the main reason why my example uses an approach that can be used on any existing store, without the need for subclassing.

Still in search for the best approach!

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

@Odrakir did you ever take it further? Your solution seems to be nice, is it then that you can mix and match traditional vs rx store subscription? I'm also wondering what you do with the rxMiddleware..

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

@Odrakir Nice, is there all ready something in there I could use.. I'm at the beginning of a new project. I did some projects with MVVM + Rx in the past and one small project with ReSwift, so thats why I'm interested in using both this time. Though admitting it is based on a gut feeling, I think Rx + ReSwift should be awesome.

from reswift.

Odrakir avatar Odrakir commented on May 30, 2024

I'm using in for two things:

  • Sending Async Actions to the store as an Observable<Action>
  • Subscribing to changes to the state Observable<AppState>

There are already some of those ideas in my repo, but as I said, a better version is on the works.

There are other approaches to mixing rx with redux, another one of them is this one: https://medium.com/@benlesh/redux-observable-ec0b00d2eb52#.a19u7dfh0

from reswift.

Odrakir avatar Odrakir commented on May 30, 2024

That's great stuff, @Qata. I like the way yo merge every action into a single signal.

Finally, after much work around this in a real project, I think I'm opting for not touching ReSwift's code and just adding two extensions:

  • A RxMiddleware which gets actions in the form of an Observable
  • A wrapper around the Store to add that rxMiddleware automatically and also to convert subscription model into Observables.

My idea also implies using a Context I can pass to actions to do dependency injection using the Reader Monad. So async actions are not just Observable<Action> but rather ReaderT<Context,Action>. That part is a little more complex, I'll try to write a blog post about it soon. (for a start there's some info at the end of this article)

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

Though I really like your work @Qata, I tend to agree with @Odrakir. I think extending ReSwift to make it Rx'able has the advantage that any fixes or feature additions to the plain ReSwift will be more transparant and easier to maintain in the extension(s).

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

@Ben-G @Odrakir @Qata, Question; For a current project I use a more simple flow. I use AsyncActionCreators for Observables (e.g. API calls) and in the subscription of these, use the callback param to dispatch actions with the obtained values. So, basically wrapping the side effects in an AsyncActionCreator. Anyone can tell me why this is maybe not the best approach?

from reswift.

Odrakir avatar Odrakir commented on May 30, 2024

So basically you are dispatching plain actions, but those dispatch calls occur for every event of an Observable. Right?

I think that should work.

My approach is a little different. I'm using a middleware that subscribes to those observables and transforms them to actions, that way I can directly dispatch observables.

The other thing that I'm adding is that they are not really observables, but readers (a monad that works somehow similar to curried functions) that get a context and return a observable.

https://gist.github.com/Odrakir/c95819f2162076f2fb45a366f704028b

I'll explain soon...

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

@Odrakir you are correct. Curious to read your explanation.

from reswift.

dodikk avatar dodikk commented on May 30, 2024

@Odrakir , looking forward to hearing more details on RxMiddleware.

Would you please also explain how your approach prescribes managing the lifetime of Reader monads. As well, as the API Client and Database objects?

Thanks in advance.

P.S. In the familiar case of "Model-View-whatever" the UIViewController holds the strong reference to the presenter. The presenter owns the model facade. The model facade interacts with the network and DB services and also holds strong references of them.

I'm really struggling to find out who is responsible of

  • invoking the services (Well, I guess, it's going to be your middleware)
  • managing their lifetime and disposing the resources correctly (that was my question, actually)

from reswift.

Qata avatar Qata commented on May 30, 2024

@Odrakir You may like what I did to Middleware in my fork of ReSwift. https://github.com/ReSwift/ReactiveReSwift/blob/master/ReactiveReSwift/CoreTypes/Middleware.swift
(It's a Reader that's generic over the State but takes Actions and returns Actions)

from reswift.

erneestoc avatar erneestoc commented on May 30, 2024

I think Netflix's redux-observable framework solves async action handling in a very elegant way.
They combine their reducers with some async action emitters they call "epics"..
https://github.com/redux-observable/redux-observable/blob/master/docs/basics/Epics.md

from reswift.

grundmanise avatar grundmanise commented on May 30, 2024

Hello, everyone.
I've got a question regarding an app architecture:

When you use ReSwift & RxSwift together do you use ReSwift for a global app state and RxSwift for a component specific state (i.e. input/output, intermediary state)?
How one uses RxSwift together with ReSwift, what layer of business logic does RxSwift handles?

(I am new to RxSwift, but have been working with Redux in React Natvie)

from reswift.

svdo avatar svdo commented on May 30, 2024

Hi folks,

I'm an experienced iOS developer, and after half a year of JavaScript development using React and Redux, I became fond of the architecture pattern and found ReSwift. I have created a framework called ReRxSwift that decouples the view controllers from the application state and ReSwift actions in a manner similar to react-redux.

I would highly appreciate it if you could have a look and let me know what you think of it: https://github.com/svdo/ReRxSwift.

from reswift.

avdwerff avatar avdwerff commented on May 30, 2024

@svdo interesting, I would like to try it out. Did you ever checked: https://github.com/ReactorKit/ReactorKit ? Guess same goal, different approach.
Another (somehow different) interesting project worth checking out from the RxSwift initial creator is https://github.com/kzaher/RxFeedback (still in its very early stage).

from reswift.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.