turing complete with a stack of 0xdeadbeef

Writing by tag

Different ways to observe properties in Swift

08 August 2021

After I wrote and released Foil, my library for implementing a property wrapper for UserDefaults, one of the criticisms on Twitter was that a mechanism for observing such properties should have been included. I disagreed. In the post I argued that this was easy enough for clients to handle on their own, but more importantly that there are too many options for how to do this and I didn’t think Foil should impose any one of them on clients.

Continue…

Is SwiftUI ready?

01 July 2021
Updated: 08 October 2021

I’ve been following what’s going on with SwiftUI since it was released with iOS 13 at WWDC 2019 and have even taken extensive notes, but I have avoided using it. As I wrote before, I mainly wanted to avoid dealing with bugs and workarounds that might make me less productive compared to using UIKit, which I know quite well. I’m very interested in learning and using it, I’m just hesitant given some of Apple’s history, like early years of Swift. I have no doubt that SwiftUI will be the future of Apple platform development, the question is when that future will arrive. This year the framework is debuting its third major release in iOS 15. How far has SwiftUI come, and is it ready for building serious apps?

Continue…

To distribute in the Mac App Store, or not

Is the app sandbox worth it? 02 June 2021

For the past few weeks I have been debating on whether or not to distribute a new Mac app via the Mac App Store or independently. I have arrived at a crossroads in development where I need to make this decision. I am mostly code-complete for my MVP 1.0 release. The question I am facing is how I want to spend the remainder of my time to cross the finish line.

Continue…

Three months of Big Sur

01 June 2021
Updated: 09 June 2021

I upgraded to Big Sur three months ago. I know I’m (fashionably?) late to this party, but here I am. This is the longest I have ever waited to upgrade macOS. It feels weird, considering WWDC is next week where we will see what is next for macOS. Big Sur still feels new to me, and announcing the next major release already feels too soon. I was avoiding Big Sur based on various reports about bugs and instability. There were not any ‘killer’ features I was eager to have, thus the main reason I upgraded was because Xcode 12.5 required it.

Continue…

Resources for learning SwiftUI

07 April 2021

A few months ago, I shared my notes and resources for learning about compilers and LLVM. It turned out to be pretty popular and folks seemed to find it useful. So I decided to do it again, but this time for SwiftUI. However, unlike learning about compilers and LLVM, I am not declaring bankruptcy with learning SwiftUI. While I have still not written a single line of SwiftUI code, I know I eventually will.

Continue…

Xcode tips for everyone

22 March 2021

Lately, it feels like every few days someone is sharing a new Xcode tip on Twitter or on their blog. They range from hidden settings to features I simply never knew about. I started saving links and planned to add a new “Xcode tips” section to my TIL repo on GitHub to reference later. But as I started, I realized that the resulting markdown file would not be easily discoverable or shareable. I thought, wouldn’t it be nice if the iOS and macOS developer community had a single place to find and share Xcode tips?

Continue…

Obscure bridgeOS crash

22 December 2020

This is a first for me. I returned to my MacBook after leaving it for a couple of hours, and it was shutdown even though I left it powered on. The machine was idle. I didn’t have any specific tasks running. I figured it might have been a macOS kernel panic, but upon rebooting I discovered that the crash was caused by bridgeOS.

Continue…

Swift deinit is (sometimes) not called for throwing or failable initializers

08 October 2020

I was never a fan of failable initializers in Swift. I do not think this is the correct place to fail and return nil most of the time. Of course, there are exceptions where a failable initializer is appropriate. But there is another behavior of which to be aware. When constructing a class via a failable initializer, init?() — or a throwing initializer, init() throws — the deinitializer, deinit, is not called if initialization fails or throws, respectively.

Continue…

How to fix the incomprehensible tabs in Xcode 12

24 July 2020
Updated: 06 October 2020

Xcode 12 was released and it includes a change to how tabs and navigation work. In Xcode 12, the tabs have their own tabs. It makes no sense to me. I know we are supposed to be nice to each other about software, but this new UI/UX is beyond incomprehensible. What made it worse is that this new “tabs within tabs” was the default setting (overriding preferences I had previously set) and I could not figure out how to restore the previous (desired) behavior.

Continue…

Swift globals and static members are atomic and lazily computed

16 July 2020

While debugging some code the other day, I wanted to verify the behavior of global variables and static members in Swift. I vaguely remembered from the early days of Swift, that static let members and global constants were atomic and computed lazily — one of the many improvements over Objective-C.

Continue…

Quickly switching between Xcodes

07 July 2020
Updated: 22 August 2021

I try to have only one Xcode installed at a time for simplicity and tidiness. But such a setup is rare as we often must manage stable releases and beta versions simultaneously.

Continue…

Mac app tests fail with hardened runtime enabled

23 February 2020

I recently discovered that unit tests and UI tests for a macOS Xcode project will fail with obscure error messages if the hardened runtime is enabled. It took me awhile to realize what the actual source of the problem was, because the error messages led me in the wrong direction. Hopefully this will save you some time.

Continue…

AppleScript to export open Safari tabs to OmniFocus

14 January 2020

I love OmniFocus. It is an indispensable app for me and a great Mac app. For managing and organizing to-do lists and personal projects, there is nothing better. Being a great Mac app means adopting behaviors that users expect, conforming to macOS UI/UX paradigms, and for the truly great mac apps it means being scriptable. I want to share two AppleScripts that I wrote for OmniFocus to automate one of my common workflows.

Continue…

Observing appearance changes on iOS and macOS

08 January 2020

I recently needed to determine when the user has manually switched between dark mode and light mode on macOS. In my menu bar app, Lucifer, the icon reflects the current appearance setting when you change it from the app — an inverted pentagram for dark mode and an upright pentagram for light mode. But there’s a bug. If the user manually changes the appearance setting from System Preferences, or if they are using the new “auto” setting in macOS Catalina, the icon gets stuck in its previous state.

Continue…

Backing up your iCloud Drive files using rsync

27 September 2019

Unfortunately, iCloud does not have a good reputation for being reliable, especially during beta releases of iOS and macOS. Yet a lot people still use it, often without any problems. I still use it, despite a few bad experiences in the past, because the best alternatives are questionable for other reasons. I’ve had good luck with iCloud Drive for the past few years, but I am terrified and paranoid of getting caught in the middle of an iCloud clusterfuck, so I backup what I have in iCloud periodically using rsync.

Continue…

Implementing right-click for NSButton

15 August 2019

This isn’t complicated, but I found it confusing. Perhaps I am spoiled by the more modern APIs in UIKit. When writing Lucifer, a menu bar app, I wanted to have different actions for left-clicking and right-clicking on the button in the menu bar. To my surprise, this was much more cumbersome than I expected.

Continue…

Summoning Lucifer: on making my first Mac app as an iOS developer

26 March 2019

I made my first Mac app — Lucifer. It is a menu bar app that allows you toggle Dark Mode on and off in macOS Mojave. To be honest, it feels like a stretch to actually call this a Mac app. It is less than 100 lines of code in a single AppDelegate.swift file and the meat of the program is an AppleScript that tells System Preferences to enable or disable Dark Mode. As an iOS developer, much of the experience was familiar. The most salient aspect, however, was learning the frustrating and obscure details of app sandboxing, the “hardened runtime”, and app notarization — altogether it was like visiting hell and giving Satan a bubble bath. Appropriate, I suppose.

Continue…

How to run sysdiagnose on iOS

And on all the Apple things 08 February 2018
Updated: 05 January 2019

When you file a radar for a bug on one of Apple’s platforms, you should (usually) always attach a sysdiagnose. A sysdiagnose provides a lot of helpful information for the person who is trying to understand how the bug happened. Amongst other things, it contains logs from various parts of the OS, and all recent crash logs. Without it, the person on the other end of your report inside Apple may not be of much help. On macOS running sysdiagnose is somewhat common, but what about iOS?

Continue…

Measuring Swift compile times in Xcode 9

Using -Xfrontend Swift compiler flags 18 September 2017

The Swift type-checker remains a performance bottleneck for compile times, though it has improved tremendously over the past two years. You could even say the type-checker has gone from being drunk to sober. To help users debug these issues, awhile back Jordan Rose added a frontend Swift compiler flag that would emit warnings in Xcode for functions that took too long to compile, or rather took too long to type-check. In Xcode 9, there’s a new, similar flag for checking expressions.

Continue…

Swift failable initializers

When failable becomes fallible, and how to avoid it 22 October 2014

Swift is still young and ever-changing. With each release, we have seen dozens of tweaks, additions, and deletions. And there is no reason for us to think that this rapid evolution will decline anytime soon. To remind us of exactly that, the latest post on Apple’s Swift Developer Blog introduces a new feature in Swift 1.1 in Xcode 6.1failable initializers.

Continue…