Comments (22)
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.
After some feedback from @agentk I've changed my implementation to add new types instead of altering existing ones.
from reswift.
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.
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.
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.
@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/:
- Data
- Communication: pending requests; file operation queue
- Control State: view-specific state
- Session State: user information, settings
- 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.
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.
@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.
@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.
@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.
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.
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.
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.
@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.
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.
@Odrakir you are correct. Curious to read your explanation.
from reswift.
@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.
@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.
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.
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.
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.
@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)
- Concurrency - protected reads HOT 2
- How to subscribe/unsubscribe store in a UIView like in UITableViewCell, CollectionViewCell etc ? HOT 1
- What's a good way to cast results of a subscription in SwiftUI to a desired output type? HOT 3
- Managing ReSwift app state inside FileDocument HOT 1
- Remove Travis from all ReSwift repos? / How to set up GH Actions
- ReSwift 7 Roadmap HOT 20
- Docs: Update outdated and vulnerable jQuery version HOT 3
- Array as a State HOT 1
- Clarification on Single Store object for an application. HOT 1
- Change visibility of Store from 'open' to 'public final'? HOT 2
- SIGSEGV on state.didSet HOT 4
- Using Inject with ReSwift HOT 1
- Testing: Waiting for store.dispatch() to complete HOT 2
- Huge CPU gap between ReSwift Store vs just SwiftUI ObservableObject HOT 1
- Crash: sometimes will crash at this point, what can i do to find the root cause HOT 11
- Crash when dispatching actions from inside StoreSubscriber.newState() HOT 2
- How to use a state on recursive screens? HOT 4
- Filter on updates not working HOT 3
- When do you upgrade ReSwiftRouter ? Now,ReSwiftRouter just depends ReSwift 5.0.0, but lasted ReSwift is 6.1.1 HOT 2
- Privacy Manifest HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reswift.