Rebuilding taphouse.io

A few months ago, when I decided I needed to update JavaScript on my server that ran both my blog and company website, I broke the company site. I wrote it a few years ago using a very early iteration of the Sails.js framework. Fast forward to today and I want to bring it back. I also have been wanting to dabble in server-side Swift. Enter Vapor.

I got the site up and running in Vapor 3 in a few days (last year I had started doing this in Vapor 2, but 3 was just released so the timing was good). I’m a big fan of what the Vapor team is doing and may yet take on a separate project based on Vapor. But that’s for another day.

Today is about Docker. I want my new company site to be housed in a single git repo (✅), and deployable using Docker. I want to have the vapor app in a container, and nginx on the front of it in a separate container. I also want to have SSL on the site, managed by letsencrypt. I’m also hoping to have a dev environment and a production environment (all self contained inside this repo).

This is where my holdup is. I’ve never used Docker, and have been inundating myself trying to figure it all out. I want to build this in the open, so I’ll be microblogging and regular blogging about my progress – however slow it may be.

My First Swift Package

I’m embarking on phase 1 of my blog rethink and have decided that whatever I do next will use the textbundle spec for file transport and storage. It will likely be some git repo or perhaps a Dropbox synced folder but all of the options that I’ve seen don’t strongly link a post together with assets. Textbundle solves that.

I think initially I might wrap Jekyll in something, so that the thing making the static site is really an implementation detail. The idea being that my server has an endpoint that would accept XML-RPC as well as micropub inputs, transform those to a textbundle and then build the static site from there.

So my first step was to download my posts stored on Ghost as well as my assets folder. I wanted a way to build textbundles out of these for easy migration. My first inclination was a Ruby script. I don’t know Ruby, so that became problematic from the start. So I turned to a more familiar language.

I made a Swift package called textbundleify, and the code is up on GitHub if you’re interested. It’s not polished in the slightest, but was a fun chance to try something new. It gets run from a directory containing Markdown files and if you give it a directory that contains pictures (or a directory of directories of pictures), it will embed linked images to the referenced textbundle.

I had to learn to use Process as well as NSRegularExpression (though I still don’t know how regular expressions really work). It was quite weird getting an NSRange for use on a Swift string, which only works on String.Range ranges. It was fun to put together over a few hours, and should do the migration trick I’m wanting.

The next step is to figure out the proper order of operations in converting textbundles (which Jekyll doesn’t support) to the structure that Jekyll does. I’ve still got Ruby learning on my horizon but at least there are a couple of wonderful souls who have offered some help to me if I need it.

Onward!

View Controllers Make Crummy Navigators

My fellow iOS developers, we have a problem. We’ve been led astray by Apple. Don’t get me wrong, iOS is great. I love writing code in Swift (and Objective-C!). I’m a fan of Xcode too. And UIKit really makes a lot of really powerful things quite easy. But allow me this hot take: View controllers should never have to deal with navigation.

There’s a long running joke about MVC actually standing for massive view controllers and navigation is a key reason. Even a relatively simple view controller with a couple of possible destinations, using storyboards and segues, needs to implement methods that could grow to be dozens of lines long and end up knowing about the implementation details of view controllers that come after them.

What are we to do? There must be some way that can keep our view controllers clean of navigation and doesn’t fight the UIKit frameworks completely, right?

There is!

If we treat view controllers like functional pieces, we can expose a small interface to interact with them and use delegation to get stuff out. Here’s a trivial example:

protocol PeopleViewControllerDelegate: AnyObject {
    func personSelected(_ person: Person, from viewController: PeopleViewController)
}

final class PeopleViewController: UIViewController, UITableViewDelegate {
    var delegate: PeopleViewControllerDelegate?
    private var people: [People]?

    func configureWithPeople(_ people: [Person]) {
        self.people = people
        // fill a table with people
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // find the person
        self.delegate?.personSelected(person, from: self)
    }
}

This view controller (while grossly incomplete) gets configured with an array of people that will fill a table view. Tap on a row and the view controller’s job is done. It hands off the person to its delegate. What happens next is out of its hands. Perhaps we’ll show a detail screen, but maybe it’s just an API call and this view controller gets dismissed. Our PeopleViewController doesn’t know, and doesn’t care. Kind of great, right?

This begs the question of what exactly is the delegate? I’ve come to really like the coordinator pattern myself. I like having objects whose specific responsibility it is to manage the flow of my app (or just a given object’s slice of the app).

There are some things that you’ll have to give up, of course. Storyboard segues are a non-starter in this pattern. This means that there are large swaths of sample code (Apple’s and others’) that you’ll need to learn to either ignore or translate into this pattern.

So let’s trim down the size of our view controllers. Let’s narrow their scopes of responsibility, and in turn we’ll get code that is more maintainable and easier to reason about. I think we will all be better off.

Childlike Faith

And calling to him a child, he put him in the midst of them and said, "Truly, I say to you, unless you turn and become like children, you will never enter the kingdom of heaven. Whoever humbles himself like this child is the greatest in the kingdom of heaven. (Matthew 18:2-4, ESV)

I was on a walk with Finnian (my 21 month old) and as we were on the sidewalk he wanted to walk on the curb that separates the sidewalk from the road. You might have heard that kids his age don’t have the greatest of balance and I can confirm those reports. So he would reach up to grab my hand to keep steady as he walked on the curb.

But the thing is, he didn’t even look at me. He just stuck his hand up in the air and went along the curb. He was confident that I would help him stay balanced by taking his hand.

It struck me the third or fourth time he did this that he had immense faith that I would help him to not fall. And then God reminded me that this is how I’m supposed to be with him. Jesus says that I need to become like a child to enter the kingdom of heaven. What does that mean?

I should stick out my hand and ask for help more often. But I don’t. During everyday life I try to go it on my own. It doesn’t even occur to me to pray while I’m figuring out some way to make something animate just right or parse a feed. But why not? Honestly, I don’t know. But I want to.

How do I do this? I come before God and ask him to help me remember him throughout the day.

Rejoice always! Pray constantly. Give thanks in everything, for this is God's will for you in Christ Jesus. (1 Thessalonians 5:16-18, HCSB)

do not be anxious about anything, but in everything by prayer and supplication with thanksgiving let your requests be made known to God. And the peace of God, which surpasses all understanding, will guard your hearts and your minds in Christ Jesus. (Philippians 4:6-7, ESV)

Amen!

At a previous job I used to keep a post-it note on my monitor that just said “Pray”. Maybe I should bring that back and put it on the monitors I use on a day-to-day basis. That constant reminder that God is close and I’m beckoned to draw near to the throne of grace (Hebrews 4:16) could be the kickstart I need.