Hosting Downloads on Amazon S3 with CloudFront

Since early 2019, I host downloads for my app The Archive on Amazon's servers. The S3 bucket is a cheap-enough storage of the zip files, and the CloudFront cache is a content distribution network across the globe that improve download speeds. Here's a long tutorial, because I will most likely forget how I did all this in a while, and chances are you don't know how to do this either.

Continue reading …

Fixed the Blog Archive

I was looking for an old post and found that the paginated list of blog posts didn't quite contain all the posts I expected. Turns out I introduced an off-by-1 bug there, computing pages for 10 posts per page, but working with all_posts.each_slice(10-1), effectively dropping 1 post per page.

Of course my website isn't unit-tested, so no wonder :)

Add Navigation Buttons to NSTouchBar

Xcode and Safari sport Touch Bar items to navigate back and forth. Have a close look: When you put two NSTouchBarItems next to each other, there usually is a gap. Between the navigation controls, there is a mere hairline divider, but not the regular fixed-width space. They are not realized via NSSegmentedControl, though. Compare the navigation buttons with the system-wide controls far to the right: volume, brightness, play/pause. (I'm listening to the 1980s Pop Radio on Apple Music at the moment, in case you're curious.) The system controls are a NSSegmentedControl. They have rounded corners for the whole control, while the navigation buttons have rounded corners for every button. Also, the navigation buttons have the default button width.

Continue reading …

Do Not Apply Code Heuristics When You Need a Broader Perspective

You can only improve things inside the frame you pick. If your frame is too narrow for the problem you try to solve, you cannot properly take everything into perspective. That's a trivial statement as it's only re-stating the same thing, but it's worth stressing. Apply this to code. If you focus on code heuristics to improve your code base, you cannot improve the structure of your program. Even though the structure is manifested as code, it's not code you should be thinking about. It's concepts. Code is just the textual representation you stare at all day. Structure is what the imaginary entities of your invention bring forth.

Continue reading …

Refactoring The Archive's ReSwift Underpinnings

While I was refactoring my app's state recently, I noticed that there are virtually no dev logs about The Archive and how I manage state and events in this app. It's my largest app so far, still the amount of reflection and behind-the-scenes info is pretty sparse. This post outlines my recent changes to the app's state. It's a retelling of the past 5 weeks or so.

Continue reading …

Replace RxSwift View Model Types with Free Functions

Instead of writing view model types that expose the input and/or output ports as properties, consider writing free functions that are the transformation. This reminds me of Ken Scambler's proposal to get rid of test doubles through side-effect free function composition. One of his examples, simplified, goes like this: Instead of testing what customer.pay(amount, wallet) does in your tests by mocking the wallet object, you rewrite Wallet as a value object and change pay to return the effect.

Continue reading …

Programmatically Add Tabs to NSWindows without NSDocument

The Cocoa/AppKit documentation is very sparse when it comes to tabbing. You can make use of the native window tabbing introduced in macOS Sierra with a few simple method calls, though. Conceptually, this is what you will need to do: However, there are some caveats when implementing these methods naively. The plus button may stop working (no new tabs are added when you click it) and all default shortcuts are broken, their main menu items greyed out.

Continue reading …

NSAppearance Change Notifications for Dark Mode and RxSwift Subscriptions

Last year, I had a full-time job from May until November and haven't had much time to prepare for Mojave. Then it hit hard, and I am still tweaking my apps to look properly in Mojave's Dark Mode. I welcome that macOS offers two modes now, .aqua and .darkAqua in programmer parlance. Because then I don't have to implement a homebrew solution in all my writing applications.

Continue reading …