Giter Site home page Giter Site logo

Comments (2)

luizmb avatar luizmb commented on May 22, 2024 9

ReSwift is an awesome framework, I used it years ago and it was really nice. Probably you'll find a lot of articles speaking about it and other frameworks extending it, so it's what I really recommend in case you're new to redux pattern and needs something more consolidated.

However some things I wanted to make different, and now, after years working on SwiftRex and having new ideas from different sources (including ideas posted as Github issues, as you can check in the history), I believe it's getting very close to what I see as "1.0", except that docs are still outdated in some parts. I think we now have a very different implementation from ReSwift and Zendesk Suas, my main sources of inspiration when I started SwiftRex.

I'll try to list some of the differences here:

  • ReSwift uses a protocol Action which has to be implemented by your actions in order to be understood by the store. SwiftRex no longer uses such protocol, instead ActionType is generic type of the store and this is not a small difference. EVERYTHING in SwiftRex are built on top of generics parameters, making it much more type-safe, and although it makes it a bit harder to use - Swift generics are hard - more things happening in compile time protect you from runtime errors.
  • Because we rely on generics for actions and state, we can have subset of actions and subset of state, derived from the global one, and with that also derive Store, Middleware and Reducer. That means you can have a "sub-Store" which is not the store itself, only a projection of the global store to handle specific problems. Your UIViewController/SwiftUI View will no longer see the whole state, only what you choose to share. This also allows you to put views in different Swift modules and bring only the actions and state that are relevant to that view, not the whole thing.
  • Same for Middlewares and Reducers, you can have a "CoreLocationMiddleware" that will understand a state that is only "CLLocationCoordinate2D" and an action like "newLocation". You make it a Swift Package and use in any app you want, for that all you have to do is to add somewhere in your global state a property var currentLocation: CLLocationCoordinate2D and, when you plug that middleware, you pass the keypath to this property, "teaching" how to resolve the local state from the global state.
  • We think that Actions should be a enum tree, so you can resolve the sub-action from global action as well, that will enforce you to handle all the cases and compile will warn you if you add a new action and forget to handle it.
  • ReSwift has its own "reactive framework" inside of it. The subscriptions are handled by the Store and with that all the concurrency problems that are, in my opinion, better handled by RxSwift, ReactiveSwift and Combine. That's why SwiftRex doesn't implement this layer, instead we have an abstraction on top of Subscriptions, Publishers, Subscribers and Subjects, but those don't really implement any logic, they are type-erased versions of RxSwift, ReactiveSwift and Combine components. This technique is often called protocol witness (https://www.pointfree.co/episodes/ep33-protocol-witnesses-part-1).
  • There are frameworks integrating ReSwift with RxSwift, but it's not part of the core framework and I'm not sure if they release versions together to ensure compatibility, and in the end the integration happens outside of the Store, so the subscriptions will still be handled by the store.
  • You can derive your store multiple times, having a projection from another projection. This is very useful in some architectures, for example if you use MVP or MVVM, your VM can be a store projection which converts view events (button tap) into actions (userLogin) and state (valid password) into view state (button disabled). And you derive all these things using generic parameters, you can confidently and exhaustively switch over enums)
  • This is also useful for SwiftUI, because ObservableViewModel holds a projection of your store and it's the @ObservedObject expected by your View.

There are probably more differences but these are the main ones.

ReSwift is a very solid project, maintained by more than 50 contributors and with more than 6 thousand stars. It's the natural choice if you are new to this architecture and need more support from community and articles. On the other hand, SwiftRex has heavily used functional programming techniques to ensure a more safe runtime. I'm working to improve the docs and offer more tooling (integration with Redux DevTools for example https://github.com/reduxjs/redux-devtools), more complex examples and more middlewares. However, so far it's a single-person-project and I can't always go as fast as want. But I've been using it in multiple projects for the last years and it's very stable, testable and consistent. And I'm doing my best to listen the suggestions, fix bugs and help with people new to redux, regardless if they are planning to use SwiftRex or any other framework.

from swiftrex.

luizmb avatar luizmb commented on May 22, 2024

Just to be clear, when you derive a sub-Store you're not creating a second store. In "Flux" architecture you have multiple stores and must keep them in sync. Here, you have one and only one store, the same way that is suggested by ReSwift.

Deriving a store means you have something that behaves like a store (implements the same protocol), but not for the whole state only partial state (and action). But in the end, this projection doesn't actually stores anything, only redirects actions and state to the real store, running the "lift" function whenever it needs to "convert" globals into locals and vice-versa.

Before it was called ViewStore, but because it's not a store (it has no storage), the new name is StoreProjection. I like that much more :) But naming things is hard.

from swiftrex.

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.