Redux-like architecture with SwiftUI: Real World App

After looking at the Redux approach, figuring things out and writing the previous set of posts (The BasicsSide Effects and Error Handling), I wanted to put it all in practice with a real app, and decided to rewrite Bouncer (again). Here is how it went…

Bouncer is a little open-source app I wrote, that takes advantage of the IdentityLookupframework to filter unwanted messages. It is as simple as a plain text word-list, and an extension that matches message contents against it. So simple, it’s the perfect candidate to try this out.

The original version was written using an MVP+Coordinators pattern with UIKit, so the process required a full rewrite of the UI too, but the good thing is that (not considering the time I spent on design and tweaking things in SwiftUI to make it look nice) the full rewrite took me approximately 8 hours of coding work, including refactoring the Models to use Combine and writing tests for them.

If you followed my tutorials on Redux, you’d find the code to be very clear and easy to follow, and the only thing that might look a bit different is the “ContainerViews.”

To de-couple the data flow, I have used the “Container views in SwiftUI” approach Majid wrote about last year. In general, a Container View is responsible for the data flow (Dispatch actions and access our state), but does not have any User interface and passes the data to a dumb Rendering View that presents it.

The new version was written using Xcode 12 beta and the latest available beta version of iOS14, which includes new features on message filtering, its open-source too and will be available in the App Store as soon iOS 14 is released.

If you have any ideas, comments, improvements, or want to help with localization, feel free to open a Pull Request to the repo or drop me a line on Twitter.

Posts in this series

  1. The Basics
  2. Side Effects
  3. Error Handling
  4. Real World App (This Post)

Sources & Links:

6 thoughts on “Redux-like architecture with SwiftUI: Real World App

  1. Hi Daniel, thanks for the amazing tutorial. We are currently evaluating whether we should use your approach in our app but since we are all junior iOS devs we are not knowledgeable enough about the following:

    Since the entire store is injected as an EnvironmentObject in each view, we wondered if every component would re-render for every state update – even if the part of the state that is updated is unrelated to the part that some component uses (i.e. state.auth.isLoggedIn is changed in some reducer and some component only relies on state.todos). We are worried about that since we can already forsee our state growing quite large given our app logic.

    I’d be greatful if you could share your thoughts on this with us. 🙂

    1. Hi Kevin.

      You make a good point about the store being injected everywhere. As the app grows bigger you can split your app logic into different stores, and manage state independently. There would be one store containing all shared data, which would in available everywhere, of course, but for component specific logic, using a separate store makes a lot of sense here.

      Good luck with the app!

  2. Hey! Thank you for this wonderful article. I’m learning redux+swift now and it was very helpful. But i have one question: what do you think about Coordinator for Redux+SwifUI? It seems that Views are coupled tightly, when we are using pure swiftui with it’s cool navigationview, sheets, etc. I’ve found some solutions for MVVM+C on swiftui, but still looking something for redux.

Say something!