Pi-hole on Unraid (as Local DNS to Access NAS Services Without a Roundtrip to Cloudflare)

I’m accessing my Nextcloud, Linkding, Calibre e-book server, and other “cloud” services hosted on the NAS in the other room via their online domain and a Cloudflare tunnel. That means traffic essentially needs to be routed from my Mac, through Cloudflares servers online, and then … | Continue reading


@christiantietze.de | 7 hours ago

TableFlip v1.7.0 Releases with Modern Icons

As of today, TableFlip v1.7 is available as a free update for all customers, and available to download on the website. It’s a maintenance release to update everything for modern macOS, but it packs something delightful: a user interface overhaul with new icons and a modern macOS … | Continue reading


@christiantietze.de | 2 days ago

Percent-Encode HTML Form Values so That Spaces Become ‘%20’ Instead of ‘+’

I had this great idea, using URL Schemes on macOS apps, assembled by very simple HTML files that contain a only and produce a GET request so that the data is part of the URL: To my dismay, I discovered that all browsers encode spaces in input and textarea elements as plusses: +. … | Continue reading


@christiantietze.de | 9 days ago

Global Day of Code Retreat 2024 Retrospective

Whenever I can, I participate in our local software craftspeople’s Global Day of Code Retreat (GDCR) in November. Yesterday was this year’s event. It was the first time I remember where I haven’t taken away something new for myself as a programmer. I learned much more about peopl … | Continue reading


@christiantietze.de | 14 days ago

Running Unsigned Applications on macOS Sequoia

Sarah Reichelt (@troz@mastodon.social) published a short guide on how app permissions on macOS Sequoia work with unsigned apps, and how you can run them anyway. The context menu trick doesn’t seem to work anymore, and you need to go to System Settings, it seems. (I’m not yet on S … | Continue reading


@christiantietze.de | 22 days ago

Composition Over Inheritance in NSViews

I find myself looking at an NSView subclass that actually doesn’t do much. It’s an opaque container for a text field that sets a label text. “Opaque” inasmuch as its outward appearance is being view, hiding the actual component’s complexity inside. This is just one example of an … | Continue reading


@christiantietze.de | 1 month ago

Alex Ozun: Type-Driven Design with Swift (SwiftCraft 2024)

Type-Driven Design with Swift by Alex Ozun from this year’s SwiftCraft is a recommended watch. Alex covers concepts like replacing the notion of validation user input (with true/false results to represent its validity) with the notion of parsing – transforming unprocessed values … | Continue reading


@christiantietze.de | 1 month ago

Checklists Appreciated Under Stress

Recently, our family grew by +1, and we got our lovely daughter back home for a couple of days. The experience in the hospital or clinic surrounding the birthing process before, during, and after made me realize that If you read life hacks and productivity tips including checklis … | Continue reading


@christiantietze.de | 2 months ago

Typed Filters and callAsFunction

Swift is full of syntactic sugar. One particular taste of sweet is the callAsFunction feature. If a type has a method of that name, you can call an instance or value of that type like a function. That’s used in SwiftUI to pass actions around in the environment, for example. Quick … | Continue reading


@christiantietze.de | 3 months ago

Fairphone Fairbuds Are a Great Idea

I wanted to write something positive about the Fairphone Fairbuds. Here it is: They are a great idea. That’s it. Please move on. Continue reading for gory details, but this really sums it up: Replaceable batteries at the cost of a larger form factor is a tradeoff I am absolutely … | Continue reading


@christiantietze.de | 3 months ago

Expecting a Child

In the not-too-distant future of late summer 2024, we’ll be expecting our first child. This is your opportunity to share with someone willing to listen what you usually have to bash into other people’s heads: What heartfelt wisdom do you have to share? Is there anything you wish … | Continue reading


@christiantietze.de | 4 months ago

Pretty-Printing Variables, Objects, and Functions in JavaScriptCore

By default, the string output of JSValue in JavaScriptCore printing (e.g. via my console.log) will produce a mere [object Object]. That’s not very helpful. It’s simple to pretty-print objects (if they are merely data-containers) via JSON: | Continue reading


@christiantietze.de | 4 months ago

PSA: SwiftUI Button Click-Through Fixed in macOS 15

If your macOS app is a SwiftUI app with custom button styles that targets macOS 15+, you don’t need my click-through fix anymore. Reported via Feedback Assistant on 2024-04-11, FB13720950 is now closed because macOS 15 Beta 2 solved the issue. | Continue reading


@christiantietze.de | 4 months ago

It’s Never Just a Something

Primitive Obsession is not called “Primitive Preference” for a reason: we can find ourselves clinging to primitives like addicts, even when every aspect of our project nudges us, hints, and screams that we should be doing something different. It’s never just “a string”. It’s neve … | Continue reading


@christiantietze.de | 4 months ago

Logical Ranges and Character Ranges

In my recent post titled “The Rake and Its Prongs” I introduced a function towards the end, called NSRange.isValidInsertionPointLocation(at:). It’s used to consider the after-end location as part of the range. | Continue reading


@christiantietze.de | 4 months ago

Embark: Display Buffer in Dedicated Side Window

I wanted to show, just this once for this project, the *compilation* buffer in a bottom split. I also wanted the split to be dedicated, so no other buffers would occupy it by accident, and not be deleted (aka closed) when using delete-other-windows. That should be reserved for co … | Continue reading


@christiantietze.de | 5 months ago

Create Journal Note For a Previous Day in denote.el

Some days I forget to run Denote to create a new journal file for the day, and then the appropriately named note file is missing when I want to write down things later. That’s not how you use a daily journal, I know, but I use Emacs and denote.el to write down things like exercis … | Continue reading


@christiantietze.de | 5 months ago

MacMenuBar – Directory of Hundreds of Menu Bar Apps

Giles Turnbull shared a link today to a site I didn’t know: https://macmenubar.com It’s a directory of 950+ menu bar apps for macOS. I browsed it a bit, and while each page is a bit short (5 items per page), it’s great to discover new tools – and also check out UI design trends i … | Continue reading


@christiantietze.de | 5 months ago

The Rake and Its Prongs

When you type in a text editor, you always type out of some range. When your insertion point or cursor is blinking at the end of a word you just typed, you expect to still be “in touch” with the word, and that the next key you press will for example add a character to that word. … | Continue reading


@christiantietze.de | 5 months ago

The Communication Tradeoff

Documentation-writing is not a goal in itself. Code, tests, documentation – all of these are tools to communicate in writing with other programmers. That includes your future selves as it includes teammates and project collaborators. Kent Beck, “The Documentation Tradeoff”: | Continue reading


@christiantietze.de | 5 months ago

If You Use KOMA-Script, Really Do Use KOMA-Script

KOMA-Script is Omakase. If you trust the package, you’re in good hands to get consistent output from compiling LaTeX documents. I’ve been using Markus Kohm’s KOMA-Script for most of my life with LaTeX in some way or another because the package’s document classes really nail typic … | Continue reading


@christiantietze.de | 5 months ago

Fold Search Results Away in rg.el

With the power of outline-minor-mode in Emacs, you can turn any text buffer into an outline – with the killer feature of “cycling”, i.e. folding and unfolding outline elements. This includes rg.el-managed buffers, search results powered by ripgrep: | Continue reading


@christiantietze.de | 5 months ago

Declarative Text Kit: Word Ranges

I figured out a way to consistently change a NSRange, e.g. of a selection of text or the insertion point in a text view, to select surrounding words in DeclarativeTextKit. But first off: Dear heavens! This wasn’t easy. I’m still not happy with the solution. While there are three … | Continue reading


@christiantietze.de | 5 months ago

Hide macOS Menu Bar Icons (Bartender Alternatives)

Marco (@esamecar@social.lol) posted a list of alternatives. From that list, I filtered out MAS-only and Chinese-subtitled apps: I’m running Ice at the moment. You can organize menu bar icons into “always hidden” and just “hidden”. The latter will reveal itself when you e.g. click … | Continue reading


@christiantietze.de | 5 months ago

Declarative Text Kit: Token-Based Adapters

I’ve now finished adding an example adapter to get a structural representation of a Markdown code block to my app. It bridges the abstract syntax tree (or “token tree”) of libMultiMarkdown to NSTextStorage-compatible UTF-16 substring ranges – which DeclarativeTextKit works with, … | Continue reading


@christiantietze.de | 5 months ago

Declarative Text Kit: Reduction in Ugly Code Size

I started working on DeclarativeTextKit mostly out of desperation, because the naive approach wouldn’t do the trick any longer. I complained about this on Mastodon in the beginning, but until now, I haven’t actually shown the code that made me want to change things. | Continue reading


@christiantietze.de | 5 months ago

Declarative Text Kit: Expression and Evaluation

In DeclarativeTextKit, I found the abstraction of an “expression” in my vocabulary to represent the Domain-Specific Language’s instructions useful. Here is an example of a valid block of changes: This uses two kinds of Swift Result Builder to define the DSL’s grammar: The rules o … | Continue reading


@christiantietze.de | 6 months ago

Swift Package: FastSpring In-App Purchase

The recent release of TableFlip v1.6 is the first one that includes a new in-app purchase (IAP) component I assembled for my projects. It’s used in TableFlip to purchase a lifetime license within the app. With future releases, the package will support in-app purchases of consumab … | Continue reading


@christiantietze.de | 6 months ago

Declarative Text Kit: Inserting Strings and Lines With a Result Builder

There’s been progress on the Declarative Text Kit API idea, and today I want to share an insight into building a DSL with Swift Result Builders. A detail that I didn’t grok until I built it. {{TOC}} Inserting text into a string, text view, or other kind of text buffer is simple e … | Continue reading


@christiantietze.de | 6 months ago

It's Easier With Meaning

It is easier to close Threads if you have a great book waiting for you. It is easier to press pause on Spotify if you can play the piano. It is easier to avoid Uber Eats if you know how to cook. It can be hard, but it’s easier if you have something meaningful to do. This is almos … | Continue reading


@christiantietze.de | 6 months ago

Declarative Text Kit: Sketch of an API

I invested the past two weeks into making the Markdown highlighting component of my app The Archive better overall. More secure C token pointer handling, more performant token tree mutations, so faster highlighting and fewer pitfalls to worry about. | Continue reading


@christiantietze.de | 6 months ago

Use and Then Reduce Open Source Dependencies

Use open source liberally to make progress. Avoid open source dependencies in the long run if you can. Start a project by ingesting open source libraries to make progress fast and see if your product works. That’s fine. If it’s not too much, you can leave them in. But when the pr … | Continue reading


@christiantietze.de | 6 months ago

Zettelkasten (Not) Needed?

As the saying goes, if the title of a post is a question, the answer is “no”. I don’t know how you would sensibly apply that to this one 🙂 Most of the days, for most of the time, I’m a software developer. I code, I plan, I think and learn. At other times, I’m writing thin … | Continue reading


@christiantietze.de | 6 months ago

Table View Cells from Nib: How to Change the Blueprint Data to Affect New Cells

In a StackOverflow question, Thomas Tempelmann asked: How to get all TableCellView prototypes from a TableView object? […] How do I get to that TableCellView in its prototype form when I only have a reference to its TableView object, so that I can alter its tooltip for all rows a … | Continue reading


@christiantietze.de | 7 months ago

Dynamic Actor Isolation Can Help During the Transitional Phase

Matt Massicotte: Making just one type @MainActor can result in cascade of errors at all usage sites where the compiler now cannot provide that MainActor guarantee. This virality can make it really hard to incrementally adopt concurrency with targeted changes. Perhaps that’s not t … | Continue reading


@christiantietze.de | 7 months ago

Niki Tonsky: Hardest Problem in Computer Science: Centering Things

Niki Tonski with a very well-illustrated post on centering text, icons, and UI elements. The problem is explored in great detail. Every big company fails at this. Type (font) design and UI design and icon design are all part of the problem. After the build-up, this part killed me … | Continue reading


@christiantietze.de | 7 months ago

Always Be Changing Existing Code

Why change perfectly servicable code today when there are problems to solve? “I’d be changing it again next week. So where’s the value? Might as well keep it as-is.” When you are inclined to change code without defects, this could indicate a new understanding that needs expressin … | Continue reading


@christiantietze.de | 7 months ago

SwiftUI Kata: Recreating DebugInfo Viewer

Ever wanted to recreate a beautiful Mac OS X Aqua app in SwiftUI? Technical Note TN2124 contains cool debug information, and a screenshot of the DebugTest Info app. Here’s a live-coding session (24mins) to recreate the DebugTest Info app: | Continue reading


@christiantietze.de | 7 months ago

Enable SwiftUI Button Click-Through for Inactive Windows on macOS

On macOS, there’s 1 active window that receives your key input. Then there’s all the other windows, which are potentially invisible or obstructed by other windows. These inactive windows can be brought to the front and made active with a click. Then you can interact with these wi … | Continue reading


@christiantietze.de | 7 months ago

“Soulslike”

Programming is a Soulslike. Dark Souls is notoriously difficult. You need to memorize enemy movements and patterns to get good at the game. You cannot beat it casually. The “Git Gud” meme traces back to this whole ordeal: You need to become a better player, learn the movements an … | Continue reading


@christiantietze.de | 7 months ago

Masterclass of Decoupling: Diablo II Resurrected

Decoupling is hard work, especially when taken to extremes – as the team of Diablo II did when they decoupled the whole rendering stack of the original game from the rest of the engine to reuse both independently. Today I learned that Diablo II Resurrected is a true remaster: new … | Continue reading


@christiantietze.de | 7 months ago

Negate KeyPath Values with not()

Swift KeyPath is a great shortcut for property-based mapping and filtering of collections: When you need a simple transformation, the simplest probably being the boolean negation operator, you only have two choices: So either you use the key path and separate the negation – which … | Continue reading


@christiantietze.de | 8 months ago

Disable XeLaTeX Character Sequence Mappings for Inverted Question Mark and Inverted Exclamation Mark

I spend a couple of hours investigating the XeLaTeX purgatory where character mapping live. I didn’t know what these were before, too, don’t worry. I’ll walk you through it. The observable behavior is the following. Let’s say you start with Markdown with “dumb” quotes like this: … | Continue reading


@christiantietze.de | 8 months ago

You Absolutely (Do Not) Need to Comment Your Code

Of course you don’t need comments in your code. But your future self appreciates explanations: What is this nested loop good for? What is its purpose? Comments provide context, and shortcuts for understanding: “you don’t need to read this, just think of it as …” Once you explain … | Continue reading


@christiantietze.de | 8 months ago

Ship Custom Fonts within a Swift Package

I found out that you can bundle TrueType Font files (.ttf) with Swift Packages just fine. It’s not as declarative as adding Info.plist entries to your app, but the code is very simple. First, add fonts as managed resources under e.g. Sources/PACKAGENAME/Resources/Fonts/ (last sub … | Continue reading


@christiantietze.de | 8 months ago

Easing Into a Language and Environment: Week 3 with PHP

Based on the calendar, I’m about two months into a server script project for the Zettelkasten website, but measured in actual work weeks, it’s now the start of week three. I notice that I’m now in a comfortable rhythm to develop features, and that’s always an exciting milestone. | Continue reading


@christiantietze.de | 8 months ago

You're Making Apps, So You Are Working for Apple/Google/...?

Octavi Navarro reports that (some) people think (some of) his games should be free instead of paid: I’ve got hundreds of “this game should be free” angry reviews over the years but I find it shockinge every time. These are not evil corporation executives, but consumers (most pr … | Continue reading


@christiantietze.de | 8 months ago

SwiftUI Challenge: Can You Port this from Auto Layout to SwiftUI?

On Mastodon, we had a discussion about whether SwiftUI is more or less productive than non-SwiftUI app-making, and Der Teilweise (@teilweise@layer8.space) chimed in with his personal benchmark: a flexible-width window, reflowing text, and equal-size buttons. The Auto Layout versi … | Continue reading


@christiantietze.de | 8 months ago