book covers

Indie macOS Dev Bundle, Swift 3 Ed..

Design solid applications and own your distribution process. Learn software architecture principles to make your Swift apps easier to maintain and extend. Set up your app for sale, with a trial mode and license generation all set. Including fully functional sample projects and code templates for your app.

Week #17 of 2017 in Review

Since I’m going to spread my writing thin on this blog in the upcoming weeks, I thought it might be nice if I highlighted some things that were happening. So here goes.

Update 2017-04-29: Forgot the coding stuff. Is now added!

App News

Blog Posts


Other Stuff

  • Went out to paint a picture with acrylics last Sunday. Kind of happy, but I see where I can improve my strokes and technique. I’m rusty, and I never was that good in the first place, so way to go this year!

The Archive – Mac App Beta

The Archive screenshot
Early development preview of The Archive

My latest project is about to be ready: it’s a strictly plain text note-taking application. If you know our writing over at the Zettelkasten Method blog, you will know the method I’m incorporating in this app. Everything revolves about flexibility and your ownership of the notes. Plus the amazingly productive method itself is baked right into the app to guide your workflow.

Sign up here for a beta invitation in early May:

Website Changes Imminent

The past couple of weeks have been unusually quiet around here. There are a couple of reasons:

  1. I was undergoing an operation (for a nearly-but-not-really abdominal hernia that I got from squats with bad form and tons of weight a couple years back and which showed symptoms in March) and being able to sit in front of a computer again took a while. I now permanently carry a 6x11cm plastic mesh in between the fasciae of my belly. Apart from most strength training still being too painful to do, everything’s fine in my day-to-day activities.
  2. When I could, I spent all my computer time on my current soon-to-be-announced project. It’s an important milestone in my Mac application empire and there are a lot of edge cases I have to cover to prevent data loss and the like. It’s pretty huge in terms of lines of code already, surpassing both the Word Counter and TableFlip.
  3. I am planning to move the programming blog from here to someplace else. Because I don’t have an outlet for all of my stuff at the moment. Programmers will be able to read my posts and notice my books on this site at the moment, but app customers will have a harder time finding their way around. As I grow my empire, I want to take better care of everything. I migrated most stuff to a GitHub Pages hosted Jekyll website. My secondary domain now points there if you want to have a look. Which means the schism is already real, it only doesn’t show on this website, yet.

Then there’s a lot of preparation happening for side-projects and my stuff at the Zettelkasten Method blog where we will run a live video stream today, by the way.

So the delay here is due to managerial problems and some re-structuring. I hope to clean up everything, soon, and then move forward with higher velocity. There’s a ton of unedited posts in my backlog waiting to be published.

FatSidebar View Component for macOS Released

One important user interface part of my latest top-secret project involves a sidebar of buttons. Like a regular toolbar, but taking up less space for chrome, looking more flat, and the user should be able to create toolbar buttons herself.

So while I was mostly sick at home for the last couple weeks, I spent my time cobbling this together. With drag and drop reordering and all.


Find FatSadebar on GitHub!

I have never written my own custom view component from scratch before. I helped improve KPCTabsControl for Swift 3 when I created TableFlip last year. And of course I participated in a lot of smaller open source projects, too. But I never started from scratch, and that was cool.

Also fun: creating the library’s own “logo”. Made it feel so much more official.

What’s cool about writing a new thing from nothingness is that I had no clue what to do and how to start. This component turned out as rather adventurous mental gymnastics because I had to leave the paths of application development I know so well. I still don’t know all the answers; what are best practices? Get something colorful on screen? Customize drawRect and draw boxes and placeholders? Partition the view into sub-components using Auto Layout from the get go? Is drawing text better handled by NSTextField labels than NSAttributedString.draw(in:) or is the overhead too much? (I still don’t know the best answer for this.)

Anyway! I ended up putting this together as a library with sample app. There are some unit tests for inserting items into the “fat sidebar”, but otherwise I find the drawing and layout related code to be absolutely hideous. Cannot come up with improvements on that front that go beyond cosmetics, though. Maybe later, with more experience.

Non-Obvious Swift: Defer

The following code works as expected:

class FooCollection {
    private var items = [Foo]()

    func removeAllItems() -> [Foo] {

        defer { items.removeAll() }
        return items

But do you know what “expected” means in this case?

As a reader, you assume the author had an intention. You look for the mens auctoris and are an overall benevolent reader, I hope. Presupposing said intention, you may assume that it does something special if you put the call to items.removeAll() in a defer block.

The removeAllItems method returns an array of items. If the internal collection was empty when the return statement is reached, that’d be pointless, wouldn’t it? Since your benevolent, you assume that the author isn’t stupid and that it does indeed return a non-empty collection in some cases.

Say the author had added a documentation line:

/// - returns: Array of items that were removed.
func removeAllItems() -> [Foo] { // ... }

Now that should tip the scale! So the internal collection of items is returned and afterwards emptied. Aha! How clever!

Ze true connoisseur of Swift appreciates ze brevity of defer

As a critical reader, you should be able to solve the puzzle and call the author names. Because, why make it so non-obvious to the reader? Why the guessing that either requires manual (or unit-) testing or the Swift doc (and trust in its truth) to verify the assumptions?

I was curious about the outcome of this approach so I just tried it before writing this up. Then I deleted the “”“clever”“” code and replaced it with what I had before:

class FooCollection {
    private var items = [Foo]()

    func removeAllItems() -> [Foo] {
        let removedItems = items
        return removedItems

I prefer this any day. I hope you do, too.

Setting the Line Height of a NSTextView

NSTextView (and UITextView for that matter) have a defaultParagraphStyle attribute where you can set the text’s line height. That works swell – if you display text statically. Once the user can enter something, you can run into trouble:

  • If the user adds text in the middle of an already laid-out line of text, the paragraph style is retained.
  • If the user writes at the beginning of the line, the line height info gets lost.
GIF of the process
This is what happens when you type at the beginning of a line

It’s your usual RTF nightmare. I know this behavior from rich text editors; and I developed my own way to make sense of it in the process. It might not be what is really going on, but it’s a good heuristic: it’s just like the opposite of making a word bold, placing your cursor after that word, type, and get more bold text. There, the “bold text” information is carried on. The cursor inherits this info from the character left to it. But if you start at the beginning of a line, your cursor will not inherit what comes afterward. And since there is nothing before its position, it starts with empty info, and thus empty line height settings. Since the whole paragraph is affected by this, the latest change wins. Beginning to type at the beginning of a paragraph with empty paragraph settings removes them from what comes afterwards.

So this might not be The Truth, but it helps me deal with shitty software. I don’t want to write shitty software, though, so I look for ways out of this. I don’t intend the user to change paragraph settings; I want the text view to have a certain look and feel no matter what gets pasted or typed in it.

Hunting for Core Text/TextKit callbacks, NSTextStorageDelegate seems to provide a good customization point:

func textStorage(
    _ textStorage: NSTextStorage, 
    didProcessEditing editedMask: NSTextStorageEditActions, 
    range editedRange: NSRange, 
    changeInLength delta: Int
) {
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineHeightMultiple = 2.0
    textStorage.addAttributes([NSParagraphStyleAttributeName : paragraphStyle], range: editedRange)

Of course it makes sense to store the global paragraphStyle once and re-apply it here. I don’t know if this is the best place to put it, though. Re-applying all the NSAttributedString settings while typing might not perform best.

Also, this is affecting the “rich text representation” of the text. If you copy the result and paste it into TextEdit, say, the text will look the same, line height settings and all.

You can override the pasteboard representation to be “plain text” only in order to remove the style info and thus have it behave like the “Paste and Match Style” command from the “Edit” menu automatically.

Again, I don’t know if this is the best way to do this.

What I’d expect to create instead:

  • a text view with a “plain text” representation by default (the model)
  • typesetting customizations that only affect what is visible on screen (the view)

I imagine this to be like HTML code/browser rendering, not like WYSIWYG. What you type is not what you see. Just what you’d expect a source code editor to be like.

I’ll keep you posed as I dive deeper into TextKit and stuff.

How to Make ReSwift Actions Undoable with NSUndoManager

I wrote about using NSUndoManager + ReSwift with a Middleware. You could think of the resulting UndoMiddleware as some kind of observer of events that pass the ReSwift.Store and which puts the opposites of incoming actions on the undo stack. Why a Middleware? Because making an action undoable is a side effect.

The Middleware wasn’t exactly straightforward. It took a bit of type wrapping and boilerplate code. A “context provider” made parts of the current app state and model available to compute the opposite action. Without this context, the Middleware couldn’t know what was expected.

Today I came up with something shorter: an action creator. It works well because the actions in my current project are simple and easily reversed.

Instead of dispatching an action like this:

store.dispatch(CreateFoo(id: 1))

… you create the opposite of the action where you already do have knowledge about the context:

let creation     = CreateFoo(id: 1, content: "...")
let undoCreation = DeleteFoo(id : 1)
store.dispatch(undoable(creation, opposite: undoCreation))

Of course it takes more effort to compute it the other way around because you have to fetch the current content before you delete (that’s what the context provider of my Middleware did, too):

let id = // ...
let oldContent = foo(withId: id).content
let deletion =     DeleteFoo(id: id)
let undoDeletion = CreateFoo(id: id, content: content)
store.dispatch(undoable(deletion, opposite: undoDeletion))

Chances are you have a lot of the pieces of the puzzle to assemble the “undo” action in the service object that dispatches the original action. In contrast, the Middleware knew nothing and thus had to depend on another source of information for everything.

The undoable action creator is very simple, after all:

public func undoable(_ action: Action, opposite: Action?)
    -> (AppState, DefaultStore)
    -> Action?
    return { (appState: AppState, store: DefaultStore) -> Action? in
        if let undoAction = opposite,
            // Replace this with something useful in your app:
            let undoManager = getUndoManagerFromSomewhere() {
            undoManager.registerUndo(withTarget: store) { store in
                store.dispatch(undoable(undoAction, opposite: action))
        return action

This assumes symmetry of actions: inside the registerUndo block, undoable is called again, only the other way around, to setup what “redo” should be like. If your original action is not what you want to use for redoing, then you need to put that in somehow.

This is the case in my app where DeleteFoo creates a pending file change that ends with dispatching DeleteFooCompleted. The opposite of DeleteFooCompleted is CreateFoo – but the opposite of CreateFoo is DeleteFoo, not DeleteFooCompleted, so I put a mapping in between:

public func redoable(basedOn action: Action) -> Action {
    switch action {
    case let action as DeleteFooCompleted:
        return DeletingFoo(id:

        return action

public func undoable(_ action: Action, opposite: Action?)
    -> (AppState, DefaultStore)
    -> Action?
    return { (appState: AppState, store: DefaultStore) -> Action? in
        if let undoAction = opposite,
            let undoManager = getUndoManagerFromSomewhere() {

            // Original trigger might be a 'completion' event that has to be
            // "redone" using a 'starting' event.
            let redoAction = redoable(basedOn: action)

            undoRegistrar.registerUndo(withTarget: store) { store in
                store.dispatch(undoable(undoAction, opposite: redoAction))
        return action

And that’s it!

The biggest problem is to obtain a reference to the main window’s UndoManager instance. You can inject it once but not replace it later, which I would have needed, so I end up with a getter here, which I don’t like a lot; you might be fine with providing a custom UndoManager instance during setup, though! In NSDocument-based apps, where each document has its own window with its own undo manager and probably its own store instance, it’ll be pretty easy.

Handle Pending File Changes with ReSwift as Your Backbone

Automatic saving of changes in some user interface component to a file should be handled differently when you employ ReSwift.

sketch of the information flow
Your UI tells the app it finished editing. Then a reducer enqueues a pending file change.

In short, you have to extract the state information from the “save file” action and store it in the overall app’s state somehow. I append these to a collection of PendingFileChanges, a ReSwift.StateType that is part of my overall app state.

(This is a follow-up to my previous musings on the topic.)

“Save file” has the state info of “which file” and “what contents”. In order to enqueue multiple changes to the same file, add a UUID to each file change to identify the event:

struct FileContentChange {
    let url: URL
    let content: String
    let uuid: UUID

Instances of this type are enqueued with the PendingFileChanges substate. I used real FIFO queues at first and solely relied on the order, but later switched to simple arrays. I’ll tell you why in a minute.

struct AppState: StateType {
    var pendingFileChanges: PendingFileChangesState = .empty

struct PendingFileChangesState: StateType {

    static var empty: PendingFileChangesState {
        return PendingFileChangesState(fileContentChanges: [])
    public fileprivate(set) var fileContentChanges: [FileContentChange]

    public var nextFileContentChange: FileContentChange? {
        return fileContentChanges.first

    public mutating func insert(fileContentChange: FileContentChange) {

    public mutating func remove(fileContentChange: FileContentChange) {
        guard let index = fileContentChanges.index(of: fileContentChange) 
            else { return }
        fileContentChanges.remove(at: index)

Some long-running service object will listen to changes to this substate and perform the necessary writes periodically.

To simplify the setup, make the resulting ChangeFileContents service object a ReSwift.StoreSubscriber; now it’ll receive updates to the app state from your store. Cache the last received (and thus pending) change in the service so you can make the operation asynchronous and allow more incoming state updates without issuing to overwrite the file time and again with the same stuff.

When it finishes a write operation, it in turn dispatches an action so the fitting item is removed from the queue.

Here’s a sample service wireframe:

typealias DefaultStore = Store<AppState>

class WriteFileChanges: StoreSubscriber {
    let store: DefaultStore

    public init(store: DefaultStore) { = store

    fileprivate(set) var lastChange: FileContentChange?

    public func newState(state: PendingFileChangesState) {
        // If the state update shows the queue is empty, 
        // reset the cache.
        guard let change = state.nextFileContentChange else {
            lastChange = nil
        // Skip identical, unprocessed updates.
        guard change.uuid != lastChange.uuid else { return }
        // Set the cached value to prevent duplicate changes.
        lastChange = change

        delegatePerformingTheFileWriteOperation() { success in
            if !success { 
                // TODO: handle error :)
    fileprivate func delegatePerformingTheFileWriteOperation(
        completion: (Bool) -> Void) {
        // Use FileManager or String.write(toURL:) etc.

So you end up with WriteFileChanges as a service that processes a part of the PendingFileChangesState queue. To let the app know when it has finished, i.e. let a reducer remove the entry from the pending changes queue, it dispatches a CompletingFileContentChange action. I leave this simple wrapper as an exercise to the reader.

Now that you know all of the code, here’s why I ditched queues at first. With queues, I relied on the order of elements and used equality checks in the WriteFileChanges service to prevent doing the same operation twice. Before the UUID, enqueuing 2 equal FileContentChange objects resulted in the first one being processed, then popped from the queue after completion – but then the second, identical object would never be processed. Now that I think of it, since adding the UUID, the issues I had with queues is solved. So it’d actually be a better idea to use a queue instead of an array to be clear about the order. Plus make it a UniqueElementQueue or similar and add equality checks before adding elements so you don’t end up enqueuing the same thing twice while lifting this detail into the type itself.

A queue-based approach is a good idea because most apps will rely on the order of file change events. If you have write and delete operations, you will want to put both into the same queue, too, by the way, and introduce a common type for FileContentChange and FileRemoval, say.

Having written that down, I’m going to change my implementation from array to queue with the UUID and see where this leads first thing next week.

Recording of Wednesday’s Webinar

Sadly, the recording doesn’t contain the webcam stream. I find videos like this pretty hard to follow. Especially if the speaker isn’t native English, then it can be quite a pain sometimes. I hope it’s not too bad in this case!

I promised not to distribute any follow-up material until next week so that webinar attendees have early access.

But you can get a 20% discount on “Make Money Outside the Mac App Store” by using the coupon code MORECONTROL, good until March 31st!

→ Blog Archive