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:

Leave a Reply

Your email address will not be published. Required fields are marked *