Not Quite 100% SwiftUI – Time Makes Perfect

Marin’s Swift Heroes 2023 talk was just uploaded yesterday. It’s called “A 100% SwiftUI App”, and I believe you should watch it, because it’s not actually about what it says on the tin! Marin Todorov: “A 100% SwiftUI App”, Swift Heroes 2023 talk Marin’s a charismatic presenter an … | Continue reading


@christiantietze.de | 5 months ago

TableFlip v1.5.0 Released

TableFlip v1.5.0 just passed App Store Review. Direct customers got the update already. Thanks to Marin Todorov for helping on this version! The better performance with large tables, HTML export, and overall fixes are of his making ❤️ Here’s what’s new: Improved: Much better pe … | Continue reading


@christiantietze.de | 6 months ago

Sparkle v2.5 Adds Relevant Version Highlighting to Release Notes

Nathan Manceaux-Panot shared his contribution to Sparkle the other day, available in version 2.5. of the updater library: attaching CSS to parts of the release notes that are actually new to the user. Say you ship updates in x.x.1 increments to beta testers, but x.1.x updates on … | Continue reading


@christiantietze.de | 7 months ago

Portable Painter Micro Palette

Maybe you don’t know, but I’m organizing a local Urban Sketchers group in Bielefeld for 6 years. We meet regularly and draw and paint together. And that’s how I met your mother, – I’d say if you were my child. As a birthday present, I got a Portable Painter Micro palette from my … | Continue reading


@christiantietze.de | 7 months ago

UserDefaults.register(defaults:) Is a Bit Like Nil-Coalescing

I suggested the use of UserDefaults.register(defaults:) today. During the conversation, I realized that this behaves very much like the Optional/Nil-Coalescing operator ??. When UserDefaults have a stored value for a key, it’s like .some(...). When UserDefaults don’t have a st … | Continue reading


@christiantietze.de | 8 months ago

Year 36, a Retrospective

I’m usually not doing birthday posts, but a lot has happened, and it feels like more change is about to come. We got married in July. Ok, that’s the biggest change, and I could stop here. But there were other things that do pale in comparison, but which were still important: … | Continue reading


@christiantietze.de | 8 months ago

Kill Unsaved Emacs Buffers UX: Replacing Yes/No/Save with Meaningful Options

Upgrading to Emacs 29.1 worked like a charm. There’ve been a couple of small neat additions next to all the big changes like native tree-sitter support – and there’s one in particular that you could say I almost hate. Kill Anyway? Yes, No, Save and kill?! When I compose email and … | Continue reading


@christiantietze.de | 8 months ago

The Missing Array.appending(contentsOf:)

The Swift standard library has a mutating func append(contentsOf:), but not an immutable variant. Usually, the Array and Collection types offer both. I wonder why that’s not the case here. To be fair, the concatenation operator + does the same trick. Here’s a basic implementation … | Continue reading


@christiantietze.de | 8 months ago

Making Your App Extensible with JavaScriptCore: Annotated Presentation with Full Transcript

Last year, I posted my presentation video and slides for the CocoaHeads Aachen talk “Making Your App Extensible with JavaScriptCore”. Today I read about Simon Willisons’s presentation annotation tool. It’s a simple HTML file where you can put your slides, have Tesseract generate … | Continue reading


@christiantietze.de | 9 months ago

SwiftData: Store Image Data, but Actually Outside the Database

Tunds (@tundsdev@iosdev.space) shared a video tutorial about SwiftData this weekend. I hadn’t looked at SwiftData at all until now. The thumbnail read “Store Images in SwiftData”, and I was immediately worried: I recall it’s a bad idea to store megabyte upon megabyte of binary da … | Continue reading


@christiantietze.de | 9 months ago

Async XCTest Assertion Helpers

SwiftAsyncAssert by Angu (@angu@techhub.social): Instead of writing import XCTest func test_should_succeed() async { do { let isTrue = try await shouldSucceed() XCTAssertTrue(isTrue) } catch { XCFail("Should not throw an error") } } conveniently write imp … | Continue reading


@christiantietze.de | 9 months ago

Cocoa AppKit Responder Chain

The whole responder chain is traversed like the following, via the documentation for NSApplication.sendAction(_:to:from:): Start with firstResponder in the key window Try every nextResponder in the chain Try the key window’s delegate Try the same for main window, if it’s dif … | Continue reading


@christiantietze.de | 9 months ago

SwiftUI.View Is Your ViewModel

Remember when I wrote about MVVM and eventually in 2015 produced this: I learned that the “view model” in the architectural style of MVVM is a “model of the view” instead of a “model for the view”. Let me explain the difference and the benefits of being able to chose between bo … | Continue reading


@christiantietze.de | 9 months ago

Decoupling SwiftUI.View Configuration from Layout and Action Handling

Say you have a view component. You can control which sub-components it displays for maximum reuse. One day, you end up configuring the available effects, or actions, of the view component. Let’s say it’s something like this, a made-up example: enum AvailableAction { case cancel … | Continue reading


@christiantietze.de | 9 months ago

Inverted E-Mail Blockquotes

Is the following a thing in the U.S. of A, or common anywhere else, and I just didn’t notice that? For about a year, some people reply to email questions by interspersing their replies with my questions. That’s good in general to provide context. But what I don’t understand is th … | Continue reading


@christiantietze.de | 10 months ago

Super Saturday Sharefest: Matt Massicotte's XPC Work

Ok ok, I know Super Saturday Sharefest is not a thing, but it’s too late for Follower Friday, alright? I want to give a big shout-out to Matt Massicotte of ChimeHQ for dropping another awesome Swift open source package that makes using XPC Swift-ier. I’m really grateful for all t … | Continue reading


@christiantietze.de | 10 months ago

WordCounter v1.6.6 Released

I have released a maintenance update to my app, WordCounter. Check out the release notes. Some old code went out, some updated components went in. Most notably the date range picker from the statistics: Latest date range picker of your stats Since this update is built on modern m … | Continue reading


@christiantietze.de | 11 months ago

macOS Sonoma Menu Section Headers Look a Bit Off

Screenshot from “What's New in AppKit” (WWDC 2023) In my opinion, the new section headers of NSMenu don’t have enough top margin. In the WWDC 2023 example, there are no “descenders” in the menu title typo of e.g. “Section 2”. (Descenders are e.g. the lower-case g or p going below … | Continue reading


@christiantietze.de | 11 months ago

Swift Package Import in Objective-C Might Just Work

My recent posts were about SwiftUI quirks and annoyances, so I want to share a short success story for a change: You can @import Swift Packages in Objective-C code just fine. (At least if they are Objective-C compatible.) How I Got Here I updated my WordCounter app to rely less o … | Continue reading


@christiantietze.de | 11 months ago

SwiftUI.List with Menu with Plain Button Style Breaks Event Loop

With Xcode 14.3.1 on macOS 13 (Ventura), I found that you cannot put SwiftUI.Menus inside Lists without breaking the key event loop – iff you also set the menu button’s .buttonStyle(.plain)! This pesky menu, when using a plain button, breaks the app Once that button style is used … | Continue reading


@christiantietze.de | 11 months ago

How to Inspect SwiftUI.TextField.onSubmit and Figure Out You Can't Programmatically Use It

I wanted to know how a SwiftUI TextField gets to know its onSubmit handler to wire my own NSViewRepresentable to it (would be the same for a UIViewRepresentable). There’s no key for that block in the EnvironmentValues structure that you get from the “context”, though. Naively (sp … | Continue reading


@christiantietze.de | 11 months ago

Swift Pattern Matching with Extra Conditions, and the Value of Syntax Summaries

Natalia Panferova writes about Swift enum pattern matching with extra conditions and goes over: switch-case statements, switch-case statements with where clauses, for-in loops with where clauses, while loops with extra conditions (case let matching), if-case statements. (M … | Continue reading


@christiantietze.de | 11 months ago

11 or so Android Ebook Reader Apps for Academic Writing Workflows: Annotations are Hard

Here’s my personal comparison of Android ebook readers for my Boox eink tablet. I would love to add drawings as annotations. Ratta Supernote devices do this splendidly by storing the pencil input directly, without handwriting recognition. (Example here.) This is the gold standard … | Continue reading


@christiantietze.de | 11 months ago

BOOX Vector PDFs Are Already Colored

After my interesting journey into replacing greyscale values in the vector PDF export of Onyc BOOX Notes, some brainiac on Mastodon pointed out that there are non-grey colors I could use. (Seriously, thank you Jeroen :)) Some default pencil colors, exported from the greyscale dev … | Continue reading


@christiantietze.de | 11 months ago

Colorize Onyx BOOX Notes Vector PDFs (Really Rough Edition)

Sacha Chua has this nice Python script to colorize her SuperNotes sketches. Can’t be that hard to apply color replacement to the notes from BOOX devices, can it?!?! The example note I had this exported vector PDF lying around: Screenshot of the original PDF file in all its greysc … | Continue reading


@christiantietze.de | 11 months ago

Boox NeoReader Annotation Export Is Meh

When you use the built-in “NeoReader” on a Boox tablet, you get the best pencil input and quite good highlighting and annotation support. If you don’t have a Onyx Boox eink tablet with that app installed, don’t bother looking for it on the Android/Google Play Store – that app i … | Continue reading


@christiantietze.de | 11 months ago

Safari (for Mac) URL Scheme

This will open my website in Safari on macOS, no matter your default browser: x-safari-https://christiantietze.de Try it! Depending on your platform and browser, this may not be clickable or not do anything (I have no clue what Android browsers would do with this). I was looking … | Continue reading


@christiantietze.de | 1 year ago

Detach Xcode Console -- via Terminal

I have been complaining on social media about the Xcode Console sticking to the bottom, and how I’d prefer a horizontal split etc. And there have been good suggestions to e.g. open a new Console tab or window. (Thanks Dominik Hauser for the tip!) That didn’t stick because I neede … | Continue reading


@christiantietze.de | 1 year ago

Wrap HTML Tables in Figures using Nanco and Kramdown

I noticed that on mobile phones, wide tables wouldn’t scroll horizontally – instead, they broke out of the content container and everything looked a bit wonky. My goal: wrap in and add figure { overflow-x: scroll; } to make the table scrollable inside its container. Initially, … | Continue reading


@christiantietze.de | 1 year ago

Website Rank in Common Crawl's C4 AI Dataset

The Washington Post published an article, “Inside the secret list of websites that make AI like ChatGPT sound smart”, that visualizes a bit of the C4 data model via websites that have been crawled. Scroll down a lot to “Is your website training AI?” (direct anchor link), and you … | Continue reading


@christiantietze.de | 1 year ago

Fetch Personalized Command Explanations with 'um' from Your Terminal

I stumbled upon this page: http://ratfactor.com/cards/um Dave Gauer describes how he has a shell script, um, that he can use as a man replacement to help remember how to use a command. Dave’s implementation uses the cards} from his own Wiki, because the um pages there are “consol … | Continue reading


@christiantietze.de | 1 year ago

Create FastMail Masked Email Addresses with maskedemail-cli

I’m a happy FastMail user. If you want to be a happy, too, use my referral code for 10% off of your first year (and I’ll get a discount, too!) → https://ref.fm/u21056816 I never used their Masked Email feature, though, because it’s so cumbersome to create these addresses from … | Continue reading


@christiantietze.de | 1 year ago

VIPER Added to the Wiki

I was adding “tech stacks” to my CV and figured I might as well link the tech to articles or overviews on my page. The ‘wiki’ pages I added some time ago are the best places to summarize topics and embed a list of related posts. So I added a page about VIPER and briefly had a loo … | Continue reading


@christiantietze.de | 1 year ago

Copilot for Xcode Works Okay

I’ve never touched GitHub Copilot in all these years, but at Timing, everyone was (and is) very happy with it. They recommended Copilot for all kinds of refactorings and repetetive tasks. So I figured I might give it a try and see how it works. Just yesterday, I used the Copilot … | Continue reading


@christiantietze.de | 1 year ago

TableFlip v1.4.1 Released

TableFlip v1.4.1 passed App Store review and is now released: Improved: CSV importing and exporting compatibility: better handling of Excel export data, and quoted cell contents. Fixed: Edit > Copy Row didn’t copy the selected row properly. Fixed: Crash when copying a CSV-imp … | Continue reading


@christiantietze.de | 1 year ago

PSA: FileManager.trashItem (Maybe) Uses NSFileCoordinator Under the Hood Automatically, So You Shouldn't to Prevent Deadlocks

Users of The Archive and Dropbox have reported issues with deleting files in their Dropbox-managed folders in the past weeks: the app would beachball forever. Apparently, Dropbox’s recent migration from ~/Dropbox to ~/Library/CloudStorage affects this. I had the occasional Google … | Continue reading


@christiantietze.de | 1 year ago

Xcode Requires A Lot of Data for Swift Package Resolution

Xcode on mobile data after resolving packages once: 45MB required This picture shows one of the weird annoyances with Xcode and Swift packages. One package resolution step swallowed 45MB of my data. You’ve likely heard it elsewhere: when iOS developers need to work with Swift pac … | Continue reading


@christiantietze.de | 1 year ago

Getting to Know Jetpack Compose by Comparing Concepts with SwiftUI (Markus Müller's CocoaHeads Leipzig Presentation)

Markus Müller (@m_mlr) recently did a presentation at CocoaHeads Leipzig about Jetpack Compose. – Thanks for the inspiring presentation, Markus! I learned a lot. The similarities are interesting, but the differences in the build tools was also striking. The JetBrains IDE did a gr … | Continue reading


@christiantietze.de | 1 year ago

Dictionary.init to Make Use of Swift.Identifiable

In my conceptual post about equality vs identity, I mentioned Helge Heß’ advice to use a Dictionary with an ID as key, and the identified object as value when you would (wrongly) reach for Set and Hashable. I found a code snippet for this from late last year just for this! The in … | Continue reading


@christiantietze.de | 1 year ago

The Difference between Entity and Value Object, and How They Relate to Swift's Identifiable and Equatable Protocols

Helge Heß recently posted on Mastodon that he “still find[s] it disturbing how many #SwiftLang devs implement Equatable as something that breaks the Equatable contract, just to please some API requiring it. Feels like they usually should implement Identifiable and build on top of … | Continue reading


@christiantietze.de | 1 year ago

woolsweater's SF Symbols Modeline

After discovering how to use SF Symbols in Emacs on Mac, folks on Reddit shared links where Josh Caswell (known by his handle “woolsweater”) did stuff like this ages ago. This is how the SF Symbol glyphs render if you can actually see them. I.e, outside the browser's code preview … | Continue reading


@christiantietze.de | 1 year ago

Use San Francisco Font for SF Symbols Everywhere in Emacs

Today I learned that you can tell Emacs to use fontsets (or just “fonts”) for specific character ranges. Thanks to Alan at idiocy.org for the explanation! His example is this: (set-fontset-font t '(? . ?) "Segoe UI Emoji") Now instead of Emoji, which work fine in Emacs for me ou … | Continue reading


@christiantietze.de | 1 year ago

Display a Random Inspiring Quote for Journaling or Shell Prompts

The odd title gives it away – I don’t have a good use-case for this :) Dr. Drang shared how he displayed one random line of “Oblique Strategies” in his email signatures many years ago. The “Oblique Strategies” can be found here: http://www.rtqe.net/ObliqueStrategies/Edition1-3.ht … | Continue reading


@christiantietze.de | 1 year ago

Migrating to modus-themes v4 and Going Through the Changes

New year marks the day Protesilaos releases modus-themes v4 into the wild; and my package update from MELPA already ingested preliminary changes on Friday Dec 30th (much to my chagrin, because I initially wanted to do something else than fiddling with my Emacs setup) that were ab … | Continue reading


@christiantietze.de | 1 year ago

How to Use SF Symbols in Emacs (for Tab Numbers)

Early this year, I shared my setup to get tab numbers in the form of Unicode characters like “⓪”. This week, I reduced the font size in the tab bar to 80% of the main font and make the tab bar stand out less in general. The numbers in circled didn’t look so great then anymore, an … | Continue reading


@christiantietze.de | 1 year ago

Better org-mode Agenda display-buffer-alist Settings

In the previous post I showed some settings to manage a tab dedicated to Org Agenda and its related org files. I also mentioned that I didn’t like how that tab was actually handled, e.g. when I wanted to break out into other tabs. The following settings work much better for me, 9 … | Continue reading


@christiantietze.de | 1 year ago

Making Your App Extensible with JavaScriptCore (CocoaHeads Presentation)

Presentation Recording on YouTube I recently went to CocoaHeads Aachen and was asked if I happened to have a topic to talk about. Of course I did :) Designing plugins for The Archive took up a lot of my time this year. So this presentation is about the basic design of the plugin … | Continue reading


@christiantietze.de | 1 year ago

Manage Org Agenda-Related Buffers via display-buffer-alist

Emacs’s automatic window management is a bit arcane, but Mickey Petersen’s excellent article “Demystifying Emacs’s Window Manager” is full of inspiring snippets. A couple of months ago, I made some tweaks. One is to dedicate a tab to “Org Agenda”. (That’s a tab-bar-mode tab, not … | Continue reading


@christiantietze.de | 1 year ago