turing complete with a stack of 0xdeadbeef

Writing by tag

Fixing a hard-to-find bug in Dark Mode

15 July 2021

I previously wrote about implementing Dark Mode in an older codebase, specifically how Dark Mode works (or doesn’t) with CGColor. I recently fixed a bug in the same project that was difficult to track down because it manifested in such a strange way. After finding the problematic code, I realized that it is an extremely common scenario in iOS codebases — so you might have this bug in your code as well!

Continue…

Debugging a DiffableDataSource CellProvider

11 July 2021

I was recently working on a project that uses modern collection views on iOS — that is, using diffable data sources, snapshots, and cell providers. I hooked up all the components and my collection view was working, or so I thought. I started to notice some very odd, unpredictable behavior when the collection view was updated. Some of the time, the cells were updated correctly. Other times, I would see duplicates and missing data. Here’s what went wrong.

Continue…

Is SwiftUI ready?

01 July 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…

iOS 14 App Library

01 June 2021

I think App Library is one of the best features added to iOS in the past few years. I’m not being sarcastic, I know some folks dislike it. However, I absolutely loathe trying to organize apps on my phone into folders, because many apps do not have a singular, definitive category.

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…

Xcode UI testing reliability tips for iOS

17 March 2021
Updated: 18 March 2021

Xcode’s UI testing framework has had its ups and downs over the years. Most recently, it has been much more robust and reliable in my experience. However, tests still tend to flake sometimes. Here are some ways that I have been able to reduce flakiness in UI tests.

Continue…

What type is self in a Swift self-executing anonymous closure used to initialize a stored property?

The answer might surprise you 22 December 2020

In JavaScript, this pattern is called an Immediately Invoked Function Expression (IIFE) or a Self-Executing Anonymous Function. Swift doesn’t have an “official” name for this, but IIFE works as well as “immediately executed anonymous closure” or “self-executing anonymous closure”. (Thanks to folks on Twitter for helping with this.)

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…

Don't forget the keyboards

An essay 15 September 2020

You know, the thing that is actually most disheartening, disappointing, frustrating, and plainly sad about Apple’s surprise announcement today is that we will not receive any sort of response to our collective dismay. There will be no public acknowledgment, much less an apology (not that it would help much). Only silence.

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

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…

Implementing Dark Mode and using CGColor

23 March 2020

For an iOS project that I am currently working on, I am implementing Dark Mode. The codebase is approaching 7 years old, it is mostly Swift with some legacy Objective-C, and it currently supports iOS 11 and above. Aside from the tedium of ensuring the updated colors are being used throughout the codebase, I expected this task to be straight-forward. However, there were some unanticipated issues.

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…

Overriding status bar display settings in the iOS simulator

26 September 2019
Updated: 28 September 2019

With version 11 of Xcode, the IDE ships with a new feature in the simctl tool that can override status bar values for iOS simulators. This allows you to take better screenshots for the App Store without having to worrying about the time, battery level, etc. It is a great improvement, but there are some significant shortcomings. I’ve written a script to fix at least some of those.

Continue…

Debugging a subtle Swift bug that will make you facepalm

07 November 2018

The other day I was debugging a crash in a UI test for an open pull request at work. The bug turned out to be extremely subtle and difficult to notice. I spent way too much time staring at the changes, trying to understand what was wrong. Let’s see if you can spot the error.

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…

When your app is used in unexpected ways

PlanGrid as a digital archaeological tool 24 September 2017

PlanGrid is a productivity app for construction fieldworkers. The easiest way to explain it to software developers is that it’s like an IDE, Git, and GitHub or JIRA — but for construction. Think of all the amazing software tools we have to do our jobs as programmers. The equivalent tools for construction simply did not exist before PlanGrid, and they still have a lot of room to grow.

As software developers, we build software for specific purposes. We anticipate that people will use an app in certain ways. Yet, we often discover that users are behaving differently than we expected. They hack a custom, “unsupported” workflow to workaround an app’s unintended limitations. Once we realize this, we have the power to turn these user workarounds into first-class features. However, sometimes we find that our apps are being used in totally different, unimaginable ways.

At PlanGrid, we recently discovered that the app was being used as a digital archaeological tool.

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…

Officially deprecating JSQMessagesViewController

No longer maintaining or supporting this project 16 July 2017
Updated: 18 July 2017

Beginning immediately, JSQMessagesViewController is no longer officially supported or maintained. In fact, you may have noticed that it has been neglected for the past year. The most recent release was published almost exactly one year ago today. This is an incredibly difficult post for me to write and I have not made this decision carelessly. This open source project had a great run. There was (and still is) a great community around it, and I’m sorry for bringing this to an end.

Continue…

Refactoring singleton usage in Swift

Tips for a cleaner, modular, and testable codebase 10 February 2017

In software development, singletons are widely discouraged and frowned upon — but with good reason. They are difficult or impossible to test, and they entangle your codebase when used implicitly in other classes, making code reuse difficult. Most of the time, a singleton amounts to nothing more than a disguise for global, mutable state. Everyone knows at least knows that is a terrible idea. However, singletons are occasionally an unavoidable and necessary evil. How can we incorporate them into our code in a clean, modular, and testable way?

Continue…

The A5 is dead (almost)

iOS 10 drops support for A5 devices 14 June 2016

As developers, we’ve been lamenting the continued existence of the inferior A5 system-on-a-chip for the past couple of years. Both iOS 8 and iOS 9 continued to support iPhone 4S, iPad 2, and iPad Mini 1 — devices that struggled to run the OS itself. I had hoped that iOS 9 would finally drop support for these less powerful devices, but it didn’t. Today, we can finally say goodbye to the A5. Well, almost.

Continue…

Call for contributors

Join the JSQMessagesViewController team! 06 February 2016

Do you love writing code? Are you passionate about open source? Do you want to get more involved, but have yet to find a project to which you want contribute? Are you interested in contributing to a widely used, impactful project? Then I have a proposition for you! I am looking for dedicated core contributors to help maintain JSQMessagesViewController!

Continue…

Building type-safe, composable data sources in Swift

A modern approach to collection views and table views 25 October 2015

In iOS development, the core of nearly every app rests on the foundations provided by UICollectionView and UITableView. These APIs make it simple to build interfaces that display the data in our app, and allow us to easily interact with those data. Because they are so frequently used, it makes sense to optimize and refine how we use them — to reduce the boilerplate involved in setting them up, to make them testable, and more. With Swift, we have new ways with which we can approach these APIs and reimagine how we use them to build apps.

Continue…

Namespaced constants in Swift

Using nested types for clarity 19 July 2015
Updated: 23 July 2015

Mike Ash has a great Friday Q&A on namespaced constants and functions in C. It is a powerful and elegant technique to avoid using #define and verbose Objective-C prefixes. Although Swift types are namespaced by their module, we can still benefit from implementing this pattern with struct and enum types. I’ve been experimenting with this approach for constants in Swift and it has been incredibly useful.

Continue…

Using Core Data in Swift

Talk at Realm in San Francisco 25 May 2015

I recently gave a talk at the Swift Language User Group (#SLUG) meetup at Realm in San Francisco. A video of the talk is now online over at Realm’s blog, where it is synced up with my slides. If you haven’t already seen it, go check it out! Realm does an absolutely amazing job with posting these meetup talks — in addition to the video and slides, there’s a full transcript and subtitles.

Continue…

Failable initializers, revisited

Functional approaches to avoid Swift's failable initializers 06 April 2015

In a previous post, I discussed how Swift’s failable initializers could be problematic. Specifically, I argued that their ease of use could persuade or encourage us to revert to old (bad) Objective-C habits of returning nil from init. Initialization is usually not the right place to fail. We should aim to avoid optionals as much as possible to reduce having to handle this absence of values. Recently, @danielgomezrico asked a great question about a possible use case for a failable initializer — parsing JSON. Given this problem’s popularity in the Swift community, I thought sharing my response here would be helpful.

Continue…

Functional notifications

Exploring the flexibility of Swift micro-libraries 31 March 2015

The observer pattern is a powerful way to decouple the sending and handling of events between objects in a system. On iOS, one implementation of this pattern is via NSNotificationCenter. However, the NSNotificationCenter APIs are kind of cumbersome to use and require some boilerplate code. Luckily, Swift gives us the tools to improve NSNotificationCenter with very little code.

Continue…

Better Core Data models in Swift

How Swift can bring clarity and safety to your managed objects 17 February 2015

As I continue my work with Core Data and Swift, I have been trying to find ways to make Core Data better. Among my goals are clarity and safety, specifically regarding types. Luckily, we can harness Swift’s optionals, enums, and other features to make managed objects more robust and more clear. But even with the improvements that Swift brings, there are still some drawbacks and limitations with Xcode’s current toolset.

Continue…

Swift, Core Data, and unit testing

Working around Swift's constraints to unit test models 05 January 2015

Core Data is probably loved as much as it is shunned by iOS developers. It is a framework of great power that often comes with great frustration. But it remains a popular tool among developers despite its pitfalls — likely because Apple continues to invest in it and encourages its adoption, as well as the availability of the many open-source libraries that make Core Data easier to use. Consider unit testing, and Core Data gets a bit more cumbersome. Luckily, there are established techniques to facilitate testing your models. Add Swift to this equation, and the learning curve gets slightly steeper.

Continue…

Introducing JSQMessagesVC 6.0

A brief history and celebration of the popular messages UI library for iOS 08 December 2014

A few weeks ago I published the sixth major release of my our messages UI library for iOS. This release closes the door on a major milestone for this project, so I wanted to take the time to highlight its significance, discuss its new features, and examine its design. Of course, this would not have been possible without our amazing open-source community and the contributors to this project.

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…

Adaptive user interfaces

Exploring iOS size classes and trait collections 01 October 2014

When the App Store launched, there was one iPhone with one screen size and one pixel density. Designing your user interfaces was relatively simple and the technical debt of hard-coding them was cheap. Today, developers and designers face many challenges in creating apps that must work on dozens of different devices. Long gone are the days of 480x320. We can no longer depend on physical screen sizes and must always be prepared for the next generation of devices.

Continue…