Make Money Outside the Mac App Store book cover

My book is out: Make Money Outside the Mac App Store.

Own your products and know your customers: sell outside the Mac App Store. In a few hours, you’ll have in-app purchases, a trial mode, and piracy protection all set. The book includes fully functional sample projects and code ready to be copied into your app.

On Software Feedback

For some reason, I couldn’t find or load Dave Winer’s comments, so I decided to blog about it instead: Dave reported that after announcing to shutdown of his outliner Fargo in 9 months, now users just get in touch with him for the first time.

This makes me wonder: is it too hard to provide feedback from inside Fargo?

Making it easy is not the best thing to do at all times. I know one person who could say something along the lines of: “I don’t want to make things easy for people. I want to attract the right kind of people instead, those that really care.” That’s good advice. Especially if you do client work. Nobody really wants to deal with disrespectful/irritating/stupid/lazy/… people. So some kind of entry barrier can help filter folks out.

But I don’t want to make it hard for consumers and regular users of my software to get in touch. Now Fargo is free software. There’s that saying that people tend to behave worst when the product they’re complaining about was free or very cheap. One oft-mentioned benefit of “pro-pricing” is that you will attract customers who will care more about the software, provide better feedback, and are overall less annoying.

Side-note: All the users of my software seem to be recruited from Happy Land, where only smart and nice people reside. Thanks for being part of this, folks!

So what if Dave encourages users to write outlines in Fargo and send them as feedback? Would that help? Would it make matters worse? Will he drown in shitty e-mail? (Because he’d then be helping users stay dumb/unresponsive?)


On a related note, Brent Simmons wrote about feedback forums in beta testing. That, too, is a topic of collaboration and communication.

I plan to experiment with this. I will integrate ways to provide feedback right from within the app. Maybe even tie this to events. For example “user launches app for the first time in X days: do you miss something?” makes sense for a tracking app like the Word Counter. (Not so much for an app like TableFlip.)

Assertions in Swift Kill Your Code

Swift.assert bit me, and it bit pretty hard.

What do you expect to happen in this code:

func sendAction(application application: NSApplication = NSApp, sender: AnyObject? = nil) {

    assert(application.sendAction(self.selector, to: nil, from: sender))
}

… compared to this code:

func sendAction(application application: NSApplication = NSApp, sender: AnyObject? = nil) {

    let success = application.sendAction(self.selector, to: nil, from: sender)
    assert(success)
}

If your answer is “only the second variant will actually execute sendAction in release builds,” then you’re way smarter than I.

Until now I assumed that Swift.assert behaves similar to assertion macros in Objective-C where the code is passed through in release builds. I never cared to read the documentation:

In -O builds (the default for Xcode’s Release configuration), condition is not evaluated, and there are no effects.

This was the source of a maddening bug in TableFlip for quite a while which only occured in release builds as I found out today. Huh. So much for defensive programming in one-liners.

I’m a bit shocked that the autoclosure parameter isn’t even evaluated in release builds. But now I know. I bet I’ll never forget this. Don’t ask how long it took to find this. (Hint: 3 hours in total, maybe.)

Switch VS Checkbox in User Interface Design

switch and checkbox

On the Mac, toggle or switch widgets aren’t very common, yet. On iOS, you don’t see lots of checkboxes. This article on UX Movement points out that switches are for immediate actions while changes to checkboxes require a submit button to be pressed.

Now I think about preference panes in Mac apps. They usually perform changes to NSUserDefaults immediately. But using switches on a Mac still feels wrong. Maybe just because I’m not used to it, but still.

macOS’s Notification Center has a switch to toggle “Do not Disturb”. It works, but I don’t use it a lot, so there’s not much opportunity to get accustomed to it.

Putting ReSwift Actions on the Undo Stack Using Middleware

It took me a while to grok the use of “Middleware” in ReSwift. ReSwift’s own tests illustrate what you can do with it: you can filter or modify actions before they are passed to the Reducers, for example.

I use this in TableFlip to modify the undo stack now. Every action that’s undo-able is registered with the app’s NSUndoManager.

Take this enum of actions, for example:

struct AppState: ReSwift.StateType {
    var content: String = ""
}

enum DocumentAction: ReSwift.Action {
    case replaceContent(String, isInitialContent: Bool)
}

When a document is loaded, .replaceContent is dispatched with isInitialContent set to true. This flag is useful to not make the initial display of data undo-able. I’ll show you how I use that later. Keep in mind that when I initially created an action similar to this one, the isInitialContent flag wasn’t there. I discovered the need for it only later in the process.

“Doing” actions in the context of ReSwift means you invoke a Store’s dispatch method with a supported action. Like this:

let action = DocumentAction.replaceContent("new content", isInitialContent: false)
store.dispatch(action)

This is supposed to change the content of the document. Maybe a text field displays “new content” now; maybe it also changes the contents of a file or fires off a network request. That doesn’t matter right now. All that matters is that this action is triggered, and that I want to undo it.

Enter NSUndoManager. Registering an action with the NSUndoManager is as simple as calling registerUndoWithTarget(_:, selector:, object:). But you’ll have to do this for the redo counterpart as well. Traditionally, people put it into the same function:

class AnObject: NSObject {
    let undoManager = ... // maybe a property of the object
    func doSomething() {
        if undoManager.undoing {
            undoManager.registerUndoWithTarget(self, selector: #selector(doSomething), object: nil)
        }
        undoManager.registerUndoWithTarget(self, selector: #selector(doSomething), object: nil)
    }
}

This easily gets out of hand.

Let’s segue to registering undo actions in a bearable fashion before we continue to deal with the undo middleware.

Controlling What’s on the Undo Stack

NSUndoManager doesn’t accept the DocumentAction itself. Its API utilizes ye olde target–action to manipulate the undo stack. To transform my internal events to things that can be undone, I figured that blocks would be a good abstraction:

class UndoAction: NSObject {

    typealias Block = () -> Void

    let undoBlock: Block
    let undoName: String?
    let redoBlock: (Block)?

    init(undoBlock: Block, undoName: String? = nil, redoBlock: (Block)? = nil) {

        self.undoBlock = undoBlock
        self.undoName = undoName
        self.redoBlock = redoBlock
    }

    var inverted: UndoAction? {

        guard let redoBlock = self.redoBlock else { return nil }

        // No need to pass a `undoName` as it will be associated with the current action
        // by the NSUndoManager.
        return UndoAction(undoBlock: redoBlock, redoBlock: undoBlock)
    }
}

The inverted property switches the undo and redo block. That’s it.

To put an UndoAction on the stack, I don’t use the undoBlock directly because that doesn’t work. Instead, I register a callback which then invokes the undoBlock:

extension NSUndoManager {

    func registerUndo(action action: UndoAction) {

        registerUndoWithTarget(self, selector: #selector(performUndo(_:)), object: action)
    }

    @objc private func performUndo(action: UndoAction) {

        action.undoBlock()

        if let inverted = action.inverted {
            // When you `registerUndoWithTarget` while undoing, the result is 
            // actually put on the "Redo" side. ¯\_(ツ)_/¯
            registerUndo(action: inverted)
        }
    }
}

That’ll work. But I want to set the caption of the undo-able action in the app’s Edit menu, too, without doing much on the client side, so I utilize the amazing “double dispatch” technique – which is fancy talk for take a dependency as method parameter and send it a message with your property:

extension UndoAction {
    func register(undoManager undoManager: NSUndoManager) {
        undoManager.registerUndo(action: self)

        // Set the action name in the menu, but don't overwrite
        // the inferred name for the redo counterpart.
        if !undoManager.undoing,
            let undoName = self.undoName {

            undoManager.setActionName(undoName)
        }
    }
}

With that stuff in place, registering an action is as simple as this:

let undoManager = ...
let action = UndoAction(undoBlock: { print("undone!") })
action.register(undoManager: undoManager)

Now back to ReSwift.

Inverting User-Triggered Events

For simplicity’s sake, I only put a DocumentAction.replaceContent in this example. This particular action can be used in three cases:

  1. To display initial contents (not undoable),
  2. to show different contents in the same document window (undoable), and
  3. to undo the change and show the old contents again (redoable).

The first two cases are easy. We just have to dispatch them to the Store so the event is passed to the Reducers which in turn modify the app state. Dispatching is a one-liner for each case:

// Show initial content
store.dispatch(DocumentAction.replaceContent("Initial content", isInitialContent: true))

// Replace content because of a server callback, user request, or whatever
store.dispatch(DocumentAction.replaceContent("Replacement", isInitialContent: false))

Now the undo middleware should register the inverted action to the undo stack. Creating an inversion is still missing. For 100% content replacements, this is easy: the inversion is a .replaceContent action with the content before changes have applied.

An exemplary story goes like this:

// State = ""
store.dispatch(DocumentAction.replaceContent("Initial content", isInitialContent: true))
// → State = "Initial content"

store.dispatch(DocumentAction.replaceContent("Replacement", isInitialContent: false))
// → State = "Replacement"

undoLastActionSomehow()
// → State = "Initial content"

Here, undoLastActionSomehow() essentially equals sending .replaceContent("Initial content", isInitialContent: false) from the app state’s perspective. But the undo stack won’t work if all we do is push new messages onto it. That’s what the undone flag is good for: so that the inverted action does not end up on the undo stack, but is ignored.

Not putting the inverted DocumentAction on the undo stack again is important. NSUndoManager puts the inversion on the redo stack for you in performUndo (see code above).

Figuring out how to compute the inverted case is pretty easy in our case. It’s the action’s own responsibility to know how to do that, given a context which provides the data it needs.

extension DocumentAction {
    func inverse(context state: AppState) -> DocumentAction? {

        switch self {
        case let .Replace(_, isInitial: isInitial):
            if isInitial { return nil }
            return DocumentAction.Replace(state.content, isInitial: isInitial)
        }
    }
}

Of course TableFlip has a lot of actions that need more context than this in order to not replace 100% of the document with every change.

Distinguishing between a regular action and an action that was triggered from the undo stack is important, so that when a user triggers “Undo Replace Content”, for example, the same action isn’t pushed to the undo stack again.

/// Wrapper around `DocumentAction` to flag an action as already
/// on the Undo-stack.
private struct Undone: Action {
    let action: DocumentAction

    init(_ action: DocumentAction) {
        self.action = action
    }
}

Undone is not itself the reversal of the action. (We created that above already.) It’s just a simple marker. So there’s not much logic involved to make this come together:

private extension DocumentAction {

    var undone: Undone {
        return Undone(self)
    }

    var isUndoable: Bool {

        switch self {
        case let .replaceContent(_, isInitialContent: isInitial): return !isInitial
        default: return true
        }
    }
}

I can now mark a copy of any DocumentAction as “on the undo stack” and determine if it should be undoable with the isUndoable property.

This is how everything comes together:

extension UndoAction {

    convenience init?(documentAction: DocumentAction, 
        context: AppState, 
        dispatch: ReSwift.DispatchFunction) {

        guard let inverseAction = documentAction.inverse(context: context)
            else { return nil }

        self.init(undoBlock: { dispatch(inverseAction.undone) },
                  redoBlock: { dispatch(documentAction.undone) })
    }
}

With that in place, the (sole) DocumentAction can compute its inverse; the inversion is used to register undo actions with NSUndoManager. When the “Undo” menu item is clicked, the non-inverted original action will be put on the redo stack.

The Undo Middleware

ReSwift’s Middleware type is a bit … confusing at first:

public typealias Middleware = (ReSwift.DispatchFunction?, ReSwift.GetState) 
    -> ReSwift.DispatchFunction 
    -> ReSwift.DispatchFunction

public typealias DispatchFunction = (Action) -> Any
public typealias GetState = () -> StateType?

Returning a DispatchFunction from another DispatchFunction looked bogus to me at first: why return a closure that takes an Action and have it return another closure that takes an Action? – I didn’t realize this is a totally wrong interpretation until I read the unit tests I initially mentioned.

A Middleware ends up looking like this, with lots of explicit type annotations for your orientation:

let someMiddleware: Middleware = { (dispatch: ReSwift.DispatchFunction, getState: ReSwift.GetState) in
    return { (next: ReSwift.DispatchFunction) in
        return { (action: ReSwift.Action) in
            
            // Pass through without doing anything
            return next(action)
        }
    }
}

You see that the innermost block is the actual transformation of type DispatchFunction, taking an action and returning a transformed state, for example.

The block in the middle is not itself a DispatchFunction but it takes one and it returns one. The one it takes as parameter is the next middleware in the chain (or, in the cast of the last middleware, the invocation of the main Reducer), hence the name next. The one it returns is your transformation.

With this structure in mind, the undo middleware I use looks similar to this:

let undoManager: NSUndoManager = ...
let undoMiddleware: Middleware = { dispatch, getState in
    return { next in
        return { action in

            // Pass already undone actions through
            if let undoneAction = action as? Undone {
                return next(undoneAction.action)
            }

            if let action = action as? DocumentAction 
                where action.isUndoable,
                
                let state = getState() as? AppState,
                let dispatch = dispatch,
                
                let undo = UndoAction(documentAction: action, context: state, dispatch: dispatch) {

                undo.register(undoManager: undoManager)
            }

            return next(action)
        }
    }
}

Here, we only try to register actions we control and ignore the ReSwift.Init action, for example, by passing it through.


This was quite some work to write a ReSwift Middleware which registers events with the NSUndoManager. A lot of the work was targeted at creating UndoAction, though, which can be used independently of ReSwift in your Cocoa projects to encapsulate undoable actions. The rest was tricky only because reversing content changes is a non-trivial task. With the example I created, it was very easy to implement DocumentAction.inverse(context:).

The one thing that’s on my mind now is this: doesn’t the NSUndoManager own a piece of application state now? After all, it’s the only object that has knowledge about both the undo and redo stack.

There’s a proof-of-concept ReSwift Recorder library which records events so you can time-travel from within the app. Time-traveling achieves the same effect as undo/redo. Ditching the Cocoa framework’s well-established NSUndoManager for a proof-of-concept time travel library isn’t worth it for me, although I’d have preferred the conceptual purity of recording past events purely using ReSwift components.

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:

  1. Data flow, a.k.a. “process”. This manifests during runtime, when messages are sent and variables changed.
  2. Structure of components in code, module design, project setup, including file names and folders. I wrote about this part in length earlier this week.

When you create two classes and delegate an action from A to B, you create a structure and design the data flow. The two are intertwined and bringing them into existence essentially equals “doing software architecture” (for our purpose at least).

Why split this up analytically, then?

We should consider these two parts of architecture distinct because it adds tremendous value: you can change the flow without replacing all of the structure. Since flow and structure are intertwined, changing one will affect the other. But if the static structure seems all okay, you now can decide to keep it mostly unchanged and focus on the flow of information instead. You just have to be able to separate these two things.

This isn’t hard at the beginning. But the cognitive load adds up as the code base grows and time passes. You have to re-read code again and infer both structure and flow of the component you’re looking at: when is this method called? Where does the result go? Which other object is involved in the process? How tightly are they coupled, and can I re-use them?

This is hard work, mentally. Bad code makes the work even harder.

So I came up with this heuristic: Clean code reveals structure and processes easily.

When I set out to write clean code, improving the structure is only one part of the progress. I can split up a huge view controller into 10 objects but end up passing messages around erratically, making it harder to find out what happens when the user presses a button, say.


If flow and structure are somewhat independent, you may understand why using VIPER as the basic architectural pattern and using ReSwift to handle information flow and model updates works.

VIPER is about the structure. If you create the Wireframe which sets up a Presenter to an Interactor and a View component, you end up with a dependency graph of objects. That’s the structure I’m talking about.

ReSwift worries about the flow. It requires a Store and an app State object. Updates to the State are handled by the Store’s Reducers; the result is then passed to all interested parties. Here, you model information flow: user-triggered event objects affect the state; the state is reported back to the rest of the app. ReSwift introduces a front-end/back-end distinction, so to say, as part of its structural requirements.

Combining the two, you’ll find out that the “pull” mindset of a VIPER Interactor is outdated: user actions are handled by the data flow thanks to ReSwift. The Interactor doesn’t need to fetch stuff from a database anymore; changes to the visibleStuff collection in the State are pushed to observers. Now who’s the observer? The Presenter could be the observer, handling ReSwift’s callback newState(_:) and call its updateView(_:) method after that. The Interactor of this particular VIPER component is obsolete.

If the transformation from app State to data for the view is complex, maybe the Presenter isn’t the best place for that. In that case, I’d leave the Interactor in place. But instead of pulling data inside the Interactor, the Interactor becomes the receiver of ReSwift’s pushy notification. It can transform the data to a format suitable for this VIPER component and then pass it to its “output port,” that is the callback you have wired the Presenter to.

Like so, in simplified code:

class BananaInteractor {
    var outputPort: ((BananaViewModel) -> Void)?
}

extension BananaInteractor: ReSwift.StoreSubscriber {
    func newState(appState: AppState) {
        let bananaState = ... // from appStare
        outputPort?(bananaState)
    }
}

protocol BananaView { 
    func displayBanana(bananaViewModel: BananaViewModel)
}

class BananaPresenter {
    let view: BananaView
    
    func presentBanana(bananaViewModel: BananaViewModel) {
        view.displayBanana(bananaViewModel)
    }
}

class BananaViewController: UIViewController, BananaView { ... }

class BananaWireframe {
    // ...
    func setup() {
        view = BananaViewController()

        presenter = BananaPresenter(view: self.view)

        interactor = BananaInteractor()
        interactor.outputPort = { [weak self] in 
            self?.presenter.presentBanana($0) 
        }
    }
}

MVVM Is Quite Okay at What It Is Supposed to Do

Criticism targeting MVVM (Model–View–View-Model) from late last year essentially points out it’s not the silver bullet some take it for.1 Most of the stuff is missing the point. How are you supposed to make sense of it? What’s good advice for your project?

I want to raise awareness about the underlying issues that often go undiscussed: the use and limits of patterns like MVVM, and understanding the problems you try to solve with it.

Critical MVVM: What’s needed is a change of structure – whatever that means

MVVM, as it’s practiced, has a few problems. I linked to Soroush’s post “MVVM Is Not Very Good” in an aside before Christmas. His post’s title says it all already. Then I found Ash Furrow react to Soroush’s criticism of the pattern, “MVVM Is Exceptionally OK”, trying to find a common ground of critique.

Ash’s reconstruction of the pain points is this:

  1. MVVM is poorly-named.
  2. MVVM invites many responsibilities.
  3. MVVM doesn’t change your structure.

Both Soroush and Ash agree that MVVM is poorly named. And it can move the problem of massive view controllers to “massive view models,” if you will.

The second point is linked to the first. When you move everything into a view model, it simply becomes a garbage can. It does lots of things in different contexts.

The third point is of real interest. Both Ash and Soroush want to change the very structure of code when they encounter massive view controllers. Jason of NearTheSpeedOfLight.com phrases it thus: “We need better ways of organizing our code.” So if MVVM fails at this point, it means MVVM doesn’t provide a better structure.

People seem to expect a change of structure, a new way to organize code, but MVVM hasn’t met their requirements.

“But I just created a view model type that wasn’t there before,” you call out. Sure creating a type equals a change of structure, doesn’t it? It’s a new object type, after all! – We’ll have a look at this and find out what “structure” entails and why this intuition is wrong.

Secondly, if a change of structure is still needed, which problem is actually solved by applying MVVM? Why do people expect this in the first place, and how does such an improvement come about instead?

Does your app have a structure, and if so what does it look like?

A “change of structure” implies there is a structure in Cocoa apps for both Mac and iOS. Because we can deviate from traditional MVC to MVVM or whatever, the structure does not equal MVC. If MVC defined the structure, MVVM would’ve changed it. Also, massive view controllers could then be a feature, not a burden.

Apple’s documentation gives no additional guidance in terms of structuring your code. If we rule out MVC, there’s nothing left, it seems.

We need to come up with an answer to this on our own. (Maybe rightly so, because every app is different after all.)

Pondering the term “structure,” we can probably agree on a very abstract level that it’s something that has relationships between elements. Some things are foundational, others build on top of them. Some things are essential, others are accidental, nonessential. We have to find out what kind of elements we’re talking about to make this more concrete.

If we knew what this mysterious structure is, we could design it. Unless we’re aware of our needs in terms of designing structures, it’s likely that a structure will simply emerge from your code. According to our rough definition from above, there can be no software application without structure. (Except maybe when your app consists of an infinite loop which prints a string to the console.)

On iOS, you’re going to have a blank project with an AppDelegate and a storyboard plus UIViewController subclass. These things have a relation with one another. That’s how Apple provides guidance for structuring our apps. If your app is at least this complex, you have structure. And it grows. There’s no way around that.

The question really is this: do you consciously influence the way your application’s structure changes?

Getting a grip on structure with layers

In 2015 I’ve discussed a few example codes by other programmers. I liked what they did and tried to improve the usefulness of their examples through pointing out the seams that show how an app can include the new functionality from that.

For example:

I took isolated examples which show how a technique works and embedded it into something bigger. In other words, I did part of the hard work for you. I took the burden of integrating a pattern into an app. Each of us has to figure that to utilize something new: where does this code go? Is it a new “thing”? If it’s a thing, how do other things interact with it? These are the seams in your code.

Through that practice I let a framework to analyze the role of components emerge. It’s based on my understanding of layered architecture which is super simple but helps tremendously to divide the world into cohesive units or “modules.”

Layers help to show where particular seams are missing in particularly complex code samples. These are code samples which are simplified to bring the point home while they fail to show how you can integrate the functionality into your software. I find this is the stuff that’s often causing headaches. Especially beginners don’t have the analytic experience to decompose sample code and transmute it into their own apps.

The layers I talked about in these posts were:

  • (Domain) Model, which is kind of self-explanatory: the entities your application is about. There are subtle nuances you can take into account but we don’t worry about that right now.
  • Application logic; there reside the use cases of the software, the service objects that glue stuff together. Here’s the algorithm which pulls data from a web service and stores it locally.
  • Infrastructure, which contains persistence mechanisms and networking code. Not the actual calls, but the types of URL handlers and database accessors or whatever you got.
  • User Interface a.k.a. the View. Stuff displayed on screen. UIViewControllers are part of this. (We can argue about that, but let’s just use this prescription for the sake of this article.)

This is not The Truth, mind you. It’s just one admittedly simple way to structure an application code base. It’s a tool to think about your application on a high level that goes way beyond “class” and “method.” Simple apps may not need to distinguish between Application and Infrastructure; some complex applications need to subdivide Infrastructure further.

Think about a messy project from your past. If it suffered from massive view controller syndrome, thinking in terms of layers makes it hard to locate the view controller anywhere. Parts of it belong to networking, parts clearly belong to the view, parts deal with persisting data. Refactoring that massive view controller into types which clearly belong into one of these layers can help – help to extend the functionality further and to replace framework dependencies (switching from Parse to Realm), for example.

Mistaking MVVM for a software architecture approach is the real problem

Now MVVM is mostly concerned with the Application and UI layer: a “real” model is supposed to exist already and you’re supposed to somehow produce a “view model”.

MVVM’s proposes that a view model will be passed to view components. How? Nobody tells.

Since MVVM introductions don’t talk about this in-depth a lot, I guess most people will put the logic into a view controller out of habit. The view controller is part of the User Interface layer, though, and thus the real model enters the UI layer through that view controller. I argue that the view model is part of the UI layer and that no component in this layer should be coupled to the real model for the sake of encapsulation.

Here we have a conflict: the real model enters the UI layer but it shouldn’t. It’s an easy problem: create the view model somewhere else and pass it to the view controller instead. But where is this other place? (Why do articles about MVVM not talk about this stuff?)

The narrow focus on a pattern that doesn’t take most of the application into account is the number one source of problems.

It’s a confusion of concerns. Articles about MVVM do not help with this because that is beyond their scope. MVVM intros I know about don’t tell you how to craft an app and use MVVM as a way to structure the UI layer. Structural concerns are part of “crafting an app,” a different skill than “implementing a pattern.”

MVVM focuses on solving problems in code. Not every kind of problem but those of writing user interface code. MVVM is a pattern of the solution space, that is your code. Architecture tackles the problem space: driving a car remotely, taking selfies, catching “pocket monsters”, you name it. You can divide the problem space into things (car, engine, speed, size, grip) which you model in code (class Car, struct CarSize). Thus you get from problem space to solution space. MVVM is all about code. An architecture focuses on the plan to create a software solution. Design patterns are best practices. The “design” in “design pattern” is not about software design – it’s about designing code of components.

What the creation of software looks like, simplified:

  1. Articulate a problem that needs a solution
  2. Analyze the problem
  3. Model the problem (in code)
  4. Create an app of that

How it’s done in the real world:

  1. Articulate a problem
  2. Create an Xcode project and start building the interface
  3. Search for patterns on Stack Overflow

So here’s part of the reason why MVVM doesn’t seem to fit or solve everything it was advertised to do: it is rooted in a coding mindset which is not what you need to change (or come up with) a structure.

Layered architecture can help come up with a better understanding of the problems you have

I proposed layered architecture because it’s so simple and yet effective. Its focus on the application’s structure or architecture goes way beyond the scope MVVM can have. Understanding the difference between design patterns and software architecture is important to employ either.

The proverbial problem with having hammer and nails as your only tools is apparent most when you’re actually supposed to be painting a picture or baking a cake.

Now people give you a larger toolbox with screwdrivers and all, because they say the MVC hammer doesn’t suffice – but until you understand which tool is good for what you still won’t know why the larger toolbox doesn’t help.

Thinking in layers is all about drawing boundaries between larger-scale parts of your application. This reasoning can be employed to plan the next component’s design in advance.

Drawing boundaries inside your app makes a huge difference. Massive view controller syndrome is a synonym for “no boundaries, everything in one object”-design. MVVM helps to break up these mess across object responsibilities: you recognize the responsibility of a view model and put it into its own type. The next step to extract functionality out of the view controller is not obvious, though, if all you know is MVVM.

Say your view controller accidentally includes database code. The layers I listed above can already help to find out that there’s another layer next to the UI layer where you can move it.

Talking about even this very basic way to architect is so uncommon in the Cocoa community that I really wonder how teams get stuff done, like, at all. If nobody ever talks about any form of higher-level structures in apps, it’s reasonable to assume there is none. That’s kind of troubling: when we cannot talk about the design of an application at large, we’re left with solving micro problems, with implementing features. When there’s a lack of design, we’re inapt to improve it.

VIPER is a different phenomenon because it’s not just a design pattern

VIPER, too, became a popular topic last year (totally subjective). I guess for some people, especially beginners, there’s a choice to make: adopt VIPER or MVVM, aka “which trend should I follow?”

The dichotomy is misleading.

VIPER takes much more of an app’s structure into account than the design pattern MVVM can. That’s not a coincidence: VIPER is a software architectural style, not a design pattern.

VIPER offers a systematic approach to creating components with clear responsibilities. It comes as a framework to analyze a complete slice of a working application: from fetching data (Interactor) to passing it to the view (Presenter) and reacting to user input (Event Handler) and wiring all of them together (Wireframe). It promises peace of mind during development through reducing the likelihood that you connect objects in a way that’s not beneficial to your app. MVVM only promises to keep the view dumb.

Of course there are people who struggle to apply the principles of VIPER. Creating all the components of VIPER advocates seems to introduce bloat first and foremost: you have wireframes, presenters, interactors, the view, and model entities – “so many classes!”

What’s wrong with more types? I don’t say that more is better, but less isn’t better, either, if you have no reason.

If you hesitate to create new types just “because”, you end up stuffing everything into a view controller. Bloat is bad, sure. But proper separation of concerns among objects requires more than just a single object.

The feeling that VIPER is bloated may just as well stem from the fact that creating 5 objects to show and handle a single view controller feels … weird. If you never worked that way, that’ll be uncomfortable. Maybe that’s all of it.

Trust VIPER and see where it leads. The experience can be very educating. But it’s risky to follow the rules without knowing the reason they exist. Using VIPER works better when you’re experienced with designing structures.

One first has to learn to put event handling into one component while view setup is handled elsewhere. This is different from adding functionality you need just where you need it. That’s mentally taxing at first. It’s a challenge. You’ll be a better programmer when you learn to understand what’s happening there, but it’s still not feeling nice. (It’s the same with all kinds of training in life, really.)

Knowledge is the true bottleneck

Once you have a better grip of software architecture, you’re able to adapt VIPER more creatively.

You don’t need magic or a special gift to come up with an architectural pattern like VIPER. You need knowledge and experience and creativity. When you can come up with something on your own, you can interpret the rules of VIPER, layered architecture, or whatever else you find on the web properly. You can pick up new ideas and come up with solutions on your own instead of looking for a fitting solution out there.

Following patterns slavishly just because others tell you it’s working for them will only change the kind of problem you have. You’ll introduce knowledge debt into your application. It’s like technical debt, like introducing dependencies you don’t understand properly, only on a more general level.

With a better understanding you can utilize MVC or MVVM where appropriate. And you’ll understand that VIPER solves a different kind of problem than MVVM, and that VIPER + MVVM totally makes sense: the Presenter got data from an Interactor and prepares a View Model instance which it passes to the View. That’s may not be part of a book on VIPER, but it’s a compatible design.

The underlying inaptitude to reason about application design and architecture is one of the root causes of confusion.

Constructing a simple “about this app” screen with all 5 components of VIPER is madness. Try it; a lot of the components will turn out to be wasteful and devoid of much content. Showing static text doesn’t call for Presenters, Interactors, and input/output ports.

Every plan is bound to be poorly executed when those that execute it don’t understand what’s going on. They cannot react to changes in the environment.

VIPER is such a plan. It’s an approach to architect iOS apps. Without proper understanding of VIPER’s internal logic it’s very hard to apply it successfully.

“Coincidentally”, testing your code makes it easier to recombine components later and come up with new architectures

Here’s actionable advice:

Don’t force any architectural patterns down your throat.

Maybe your application won’t benefit from a particular architectural approach. Maybe your app is too simple or too complex for the approach you have in mind.

Trying to spring-clean existing code by forcing it into the constraints of VIPER, for example, can actually harm the project.

How can you find out what’s appropriate? What’s the measurement?

Here’s the single best thing I encountered so far: Strive for higher testability first. (I know, I know. Bear with me for a minute.)

Tests will help you get to new levels all on your own – levels where smarter people than us went before. Levels from which these people derived principles and architectural approaches.

Testing will teach you to think and reason about your code all the time. It forces you to create components that can be called from tests with ease and which sport predictable behavior. If your components can be tested in isolation, you’re free to re-combine them and let order emerge, bottom-up instead of top-down.

Most design patterns and higher level architectures make your code easier to test. That’s not a coincidence. That’s a reflection of the coming-about of the pattern.

How I distinguish the model from a view model in TableFlip

Working on TableFlip uncovered that keeping tables as columns and rows in memory doesn’t work when you want to create cells that span multiple columns. A naive approach of a 2-dimensional array is misleading. The atom of a table, the cell, is more fundamental. Columns and rows are just ways to look at the cell-based data.

TableFlip’s model has a Table which owns many Cells and cooperates with ColumnLenses and RowLenses to provide different ways to enumerate the data. I didn’t stuff a column or row based view to the data into Table. Test feedback drove me to separate table from columns and rows: the lenses’ tests don’t care about Table internals; they only expect input data in a certain way. That’s more comfortable to handle in tests. And it makes the resulting objects more cohesive and independent. High internal cohesion is very helpful to keep your overall code readable. (See CLEAN code.)

All of this core modeling is highly view agnostic. Not only does the view have no clue about the model, the model doesn’t care about the view, either.

I have the core model to make changing state as easy as possible. “Command-line interface”-easy. It can be saved, viewed, deleted – you don’t “save” the user interface.

Testing frees your mind to do creative stuff

“Is this part working? Lemme run the app and see …” – manual testing of the whole app gets tedious if the state gets more complex. Automated unit testing provides similar feedback (“Is that part working? Lemme use the class and check if the returned data is what I expected …”) only faster, more isolated – and without the manual operation.

TableFlip currently has 300 tests, most of them in the model layer (I didn’t write tests for most of the UI). With a single keystroke I can verify that 300 things work as expected. Manual testing doesn’t scale.

Another obvious downside of manual testing: Refactoring is too risky. Fear of regression, fear of breaking code again is what hinders all of us to make progress. Even the most obvious piece of ugly code can become hard to improve if you don’t know whether a change will break the app.

Unit testing is annoying a lot of times. And that’s precisely what it’s good for. It tell you when things become hard to control, observe, and change. On the upside, when testable components become the foundation of your software, you will recognize classes of collaborators.

Simple UIKit or AppKit-based apps take a couple of minutes to prototype in Interface Builder. We’re rewarded with walking skeletons of apps quickly. Tapping a button performs a visible action. Writing tests for model code is like navigating your Mac from a Terminal. Less fun. Less obvious to do.

But keep in mind that you don’t code an app in Storyboards alone. Glue code begins to appear: fetching data from Core Data takes code. Where will it go? Well, just put it into the view controller for starters and see what happens. – And thus the degradation of code quality begins.

Stop focusing on the wrong end: UIKit code

If you write unit tests early, you won’t tolerate these small quick fixes and cheats all the time. Because tests will become hard to write and maintain. And you would have to re-write production code to make it testable.

Bottom line of all this:

Your app is not about UIKit.

It isn’t about Core Data either. Or Parse. Or AlamoFire. Or ReactiveCocoa.

Neither is your app a folder full of swift files that contain structs which encapsulate business logic. This might be a nice model, like a painting is a nice depiction of the scene before your eyes, but it’s not a piece of software.

Your app is the whole running program with user-facing components. It solves problems of its users. That entails some input and some output. And a flow of information in between.

The focus was on the problem space all the time. We just didn’t notice.

  1. I wrote most of this post in December 2015. Now it’s August. I wonder where the time went …

Racing To the Top

I found this on Seth Godin’s Blog: A dollar more (vs. a dollar less):

But what happens if Lyft (or your project) decides to race to the top instead?

What if they say, “we’re always a dollar more than Uber”?

And then they spend that dollar, all of it, on the drivers…

Seth’s ellipsis has to be filled by you, the reader. What will happen? What do you think?


I think the users will expect drivers to be a little bit happier. Higher pay is always nice. The downside for me? I have to pay a dollar more. But at least I know that it goes where it’s needed instead of sinking into the infrastructure. What’s a dollar, anyway!

Remember that this mindset is not equally shared among all socio-economic groups. In Germany, I’d say this mindset is mostly employed by academics and students, or “alternatives.” It’s some kind of luxury: not having to turn every nickel twice before spending it. It’s counter-intuitive that students pay attention to these kinds of values since they don’t have that much money after all. Be as it may, poor people likely won’t enjoy spending more and won’t identify with the cause.

So what’ll happen? You attract a different kind of people because of your principles. Sticking to Seth’s example, the Lyft which pays its drivers the additional $1 will attract people who pay attention to company values while the “discount” service Uber attracts more of the troublemakers.

The Mac blogosphere is full of people praising paid software upgrades: “I’d gladly pay you (more)!” is a phrase I stumble upon a lot, it seems: these people rather pay for a service than get it for free only to see it being shut down later. This mindset of paying more for higher quality products may be the result of a selection bias. Mac users pay more for their computers. Paying for their beloved software doesn’t hurt as much. (Also, I still find Windows software ugly and clumsy in comparison in 2016.)

You’re a developer. You decide how to place your product.

You can create a commodity product, charging a few dollars to attract more people. The thing is that among these customers a lot will complain when their needs aren’t met. (Or so the story goes.)

Or you create a “pro app,” charging a lot more. And thus you attract those who value good software and pay more to support development. To some of them, purchasing software is an investment in a relationship.

Higher price with a good reason for the prica tag can be a message on its own. There are people who’ll listen. Chances are you want to get to know these folks and make their lives better because it’s so much nicer to cooperate.

Transparent NSTableView Headers

An NSTableView is usually embedded in a NSScrollView. If you set the columns not to span the full width, the two of them will take care of drawing an empty table header cell to the right so that the interface doesn’t look weird.

But I want to have a weird interface. Because TableFlip’s tables are different than the usual NTableView use cases.

screenshots of before and after the change
Before, the header spans the whole width. After, it visually stops where the table contents stop.

Now it should be even easier to see that the header cells are still part of the table and not just a block of color in the interface.

The first step is to make your NSTableHeaderView not draw full width but only existing column headers:

class NarrowTableHeaderView: NSTableHeaderView {

    override func drawRect(dirtyRect: NSRect) {

        guard let columns = tableView?.numberOfColumns
            else { return }

        (0...columns)
            .map { headerRectOfColumn($0) }
            .forEach { super.drawRect($0) }
    }
}

I am using a NSVisualEffectView on the window so this looks odd. If you don’t use a blur effect, the background color will match the default window’s color and you’ll be done.

screenshot of clip view drawing its own background
The header row draws a gray background on its own

You’ll notice that the content section of NSScrollView doesn’t draw a background while the header section draws the default background to the right of the header. That’s because NSScrollView uses two NSClipViews for what it does. One is the contentView and it behaves properly. The other is privately used for the header section and ignores the NSVisualEffectView setting. Probably because it is commonly used to draw something anyway.

To make the header clip view look truly transparent in a setup like mine, you have to add another NSVisualEffectView to the:

class TransparentHeaderScrollView: NSScrollView {

    override func awakeFromNib() {

        super.awakeFromNib()

        transparentizeHeaderClipView()
    }

    private func transparentizeHeaderClipView() {

        let clips = self.subviews.flatMap { $0 as? NSClipView }
        guard let headclip = clips.filter({ $0 !== self.contentView }).first,
            content = headclip.documentView as? NSView
            else { return }

        let visualEffectView = NSVisualEffectView(frame: NSRect.zero)
        visualEffectView.material = NSVisualEffectMaterial.Light
        visualEffectView.blendingMode = NSVisualEffectBlendingMode.BehindWindow
        visualEffectView.state = NSVisualEffectState.Active

        headclip.documentView = visualEffectView
        visualEffectView.addSubview(content)
    }
}

That does the trick.

NSDocument Weirdness: Sheet Contents Appear Disabled

When I added a sheet to display on top of TableFlips’ document, I wondered why the text field appear disabled, tabbing through elements didn’t work, and overall functionality was limited to accepting click events:

screenshot of disabled sheet
Everything appears disabled in this sheet

It turned out you have to make sure that you disable most of the NSWindow settings in Interface Builder except the title bar (NSTitledWindowMask). Only with a title bar (which is never visible in a sheet anyway) will the interaction work properly.

After ticking that checkbox, everybody’s happy:

screenshot of working sheet
Element focus works properly, including tabbing around and canceling with ESC

Sometimes, AppKit makes me crazy.


→ Blog Archive