SwiftRex - Redux for Swift with Reactive Capabilities

The SwiftRex project is similar to ReSwift in design: it’s a library to design applications with a unidirectional data flow underpinning. In contrast to ReSwift, which is around for years and years already, SwiftRex has had a fresh start and supports Combine, RxSwift, and ReactiveSwift to create state change subscriptions. That’s a nice touch. I’ll have to experiment with the library some day, but so far it looks nice and the README is full of sexy ASCII diagrams.

Model-View-Presenter, Form Validation, and a Unidirectional State Machine

As an exercise, I wrote a simple iOS scene transition from a login form (root view controller) to a success scene. I was experimenting with the Model-View-Presenter approach where view and presenter know each other, but communicate through protocols, so you program to an interface, not the implementation. I ended up using a simple state machine to represent the view’s state, and employed form validation that is represented in the types. I like how the result reads, so here’s a rundown of the exercise:

Continue reading …

RocketData is a Uni-Directional UI Component Data Source

I watched “Managing Consistency of Immutable Models” by Peter Livesey where Peter shows how RocketData works. Very worth the time! I’d call RocketData a uni-directional data source. It’s uni-directional because you set up the DataProvider as the source once, wire update notifications to view updates via the delegate property, and you’re done with the setup. Update events include:

Continue reading …

When You Code, You Design Both Structure and Information Flow

As soon as you write a piece of software, you “architect” it. Can’t get around that; but if you do not do it consciously, the resulting structure may not be great. Taking ownership of the process is important to change the result and create maintainable software. When we write/architect software, we worry about two things:

Continue reading …

Splitting the View Models of TableFlip, a Short Aftermath

Teaser image

I executed my plan from earlier this week to split TableFlip’s monolithic view model into sub-view models. The process wasn’t too complicated. The highlights: The current hierarchy of controllers in the view layer is as follows: The window doesn’t look too complicated and there truly are not that many view components involved, but still it’s quite some work to keep things well coordinated. The TableViewController file clocks in at about 400 lines of code although it mostly delegates stuff to other objects. There’s still room for improvement, but I have to see patterns, first. I even extracted NSTableViewaDataSource and NSTableViewDelegate into different objects months ago. Today I doubt this was a good idea in the first place. We’ll see.

Continue reading …

I'll Split Up the Monolithic View Model in TableFlip. Here's What I Expect to Happen

The upcoming changes in TableFlip’s user experience made me ponder how I structured the app’s modules. The bottleneck I created in my app is simple: there’s one presenter which transforms the model into a view model; the presenter defines a protocol for the view it expects and passes the view model to the object that satisfies this contract.

Continue reading …

How PlanGrid uses a Flux-Inspired Architecture to Simplify State Management

Benjamin Encz published an article about the architecture of PlanGrid.

They moved to a Flux-inspired “unidirectional flow” approach where state changes are performed in a Store (in the backend, if you will) and updates pushed to the user interface (the frontend). No ad-hoc view updates, no shortcuts. User events are emitted, handled by the store, and state updates affect the view. That’s it. So it’s always obvious how the user interface got into the state it’s in: all the details are plainly visible in the current state object.

Ben’s post is very deep and detailed. You’ll learn a ton from it:

  • architectural discussion: why “unidirection flow”, and why Flux?
  • setup of actions/events and the store type
  • basic state–view bindings via Reactive Cocoa
  • how testing stores (and views) is straightforward with this setup

I can’t wait for the next post in this series. Most of this easily applies to ReSwift, too, of course. And guess who just got inspired to refactor TableFlip so the model and view become even more loosely coupled?

How I Toggle or Switch 2 NSMenuItems from the Main Menu

I thought it’d be straigthforward and simple to make a NSMenuItem from the main menu implement a toggle – be it a checkmark or switching “Show X” with “Hide X” conditionally. Turns out that’s not quite as simple as I had hoped. Cocoa bindings would work but make things complicated. Most stuff on the web uses view tags to find items in menus. That’s not my favorite solution for anything. menuNeedsUpdate wasn’t called when I had hoped it would, either. So I tried a few different setups and settled with a boring and verbose way to switch “Show X” and “Hide X” depending on a boolean flag the current NSDocument window exposes.

Continue reading …

ReSwift, Law of Demeter, and Another Level of Indirection

Teaser image

Benjamin Encz’s presentation “Unidirectional Data Flow in Swift” about ReSwift features global app state: there’s one AppState type that acts as the facade to model and navigation state which is the single point of truth of every state in the app. This is a game changer when you suffer from massive view controller syndrome. In this post, I’d like to show you how he envisions the state of an app and what a next step could look like.

Continue reading …

Events as Declarative State

Teaser image

I think I found something better than closures to handle events. Instead of dispatching closures that are themselves the changes that should be performed, simply declare the change.

enum Action {
    case ResizeBanana(BananaId, Size)
}

Now you need some kind of action handler, which Benjamin Encz calls “reducer” in his presentation “Unidirectional Data Flow in Swift”. Think of a list of reducers as a Chain of Responsibility only without the final consummation of the action. It is passed throughout the whole responder chain. Why reducer? Because they operate similar to the reduce function. The end result will be the combined result of all reducer’s mutations.

This is cool, because no component needs to know what such an action entails – none except the appropriate reducers.

If closures were great because where you type them you can see what is going on (more like “how” in my opinion), a simple action enum is even simpler, telling what should happen.

Works well with CQRS, I imagine. Will have to write a demo app using CQRS sometime to validate.

The current project is called ReSwift and code is available on GitHub.