Josh Betz

Engineer, Automattician, Wisconsin Badger

Wire

Wire is an RSS reader for iOS that displays articles with their native formatting — or an optimized mobile version for sites that support AMP — and doesn’t require yet another account to sign up for.

As mentioned previously, it had been quite some time since I wrote any iOS apps, so I decided to use some of my free time this summer to build an app that I wanted to use.

There are other RSS readers. It’s not exactly new territory. But like most apps, the good ones all seem to require you to sign up for another account. I don’t know about you, but I find the number of accounts I already have to worry about somewhat overwhelming. I don’t need anymore. Relying on an iCloud account won’t solve this problem for everyone, but in this case it solves it for me.

The other main feature I wanted in an RSS reader was the ability to disable the monotonous E-reader-like view that has become so common. So many of the websites I read look great on mobile.

As you can see, it’s a pretty standard design. There’s a simple list of articles that you can group however you want. The article view loads a selected article in a web view. I really prefer this real view of the site to the reader-ized version other apps use.

I have found Wire to be quite good for what I want. It doesn’t do much more than aggregate articles from the websites you want to keep up with, but I think it does that well.

Core Data & Concurrency

It’s been a while since I last worked on any mobile apps, so I thought the last couple weeks of sabbatical would be a good time to get caught up on iOS and specifically to learn Swift, which didn’t exist last time 🙃. For the most part, it was pretty easy to pick up and I was able to move fairly quickly on some apps I had been thinking about.

One of the only problems I ran into was related to Core Data concurrency. Specifically, if two different threads are reading and writing data, you get errors like 'NSGenericException', reason: Collection <__NSArrayM: 0x7fabb400> was mutated while being enumerated.

The solution is private queue contexts. I won’t do a full explanation of queue contexts here, but the Apple Developer Documentation has some good information. The idea is to create a private context to operate on while we’re doing background work.

For this to work as expected there are a few things that need to happen:

  1. Set context.parent. In order for the changes to eventually be written to disk, we have to associate the new, private context with the main context by setting newContext.parent = oldContext.
  2. Use context.object(with: objectID) to make core data relationships. We need to get a reference in the current context to any objects that were created outside the context.
  3. After saving, we also need to save the parent context to commit the changes to disk. To make it thread safe, we use oldContext.perform or oldContext.performAndWait depending on whether is should be asynchronous or not.

I put together a gist to demonstrate:

The following articles were especially helpful to understand how to fix this problem in my case:

  1. Apple’s Core Data Programming Guide > Concurrency
  2. Core Data Concurrency & Maintaining a Silky Smooth UI

Automate git bisect

I occasionally use git bisect to figure out where I’ve introduced test failures. If you’re not familiar, given known good and bad commits, along with a test command, git bisect does a binary search over your repo to determine where a bug or test failure was introduced. This is especially useful on large repos with a test suite that takes a minute or two (or more 🙃) to run.

Most of the time, I just need to check the last handful of commits. To that end, I’ve written a bash function that assumes the current HEAD is bad, 10 commits prior is good, and automatically runs a test command that you define.

gbi() {
	git bisect start
	git bisect bad
	git checkout HEAD~10
	git bisect good
	git bisect run "$@"
}

This won’t cover every case, but should help automate this fairly verbose process most of the time.

Go Configure

I’ve been dabbling in Golang on and off for a little while now. Recently I was looking for a package to read and parse configuration files with the following requirements in mind:

  1. Be fast.
  2. Use environment variables and JSON files (in that order).
  3. Support hot reloading.

I looked at some of the popular configuration packages, but didn’t see anything that I loved. Many of them don’t meet the requirements I had in mind or are more complex than I’d like.

So, I decided to write config — I know, it’s a great name. It’s pretty simple. We cache values in memory to minimize disk IO. On SIGHUP (or any time you call config.Reload()), we clear the cache, so you can update the configuration without restarting your app.

Usage looks something like this:

There are more examples and details on the API in the README on Github.

If you have questions or ideas, issues and pull requests are welcome on Github. Let me know if you use it!

Github Auto Deploy

I published my first npm package over the weekend: github-auto-deploy.

I’ve been playing with Github Auto Deploys recently. There are a couple things I’m doing here that I think are different from the typical auto deploy workflow.

  1. Using the deployment event. Github has a way to differentiate push from deployment. Deployments have the added benefit of depending on Github statuses, like ci/travis-ci. Having deployments depend on a test suite is nice.
  2. Using git fetch && git checkout. Instead of doing a git pull and slowly updating files depending on the network speed, first fetch all the files and then do a quick file pointer swap to instantly update all files at once.

Example

PORT=1234 SECRET="Swifty4Lyfe" gad /var/app /var/app/bin/deploy.sh

In this example, deploy.sh might look something like this:

npm install
service node-app restart

If you have questions or suggestions, let me know!

Next Page »