A collection of primarily development-related posts, about issues that I encounter and how I fixed them. Hopefully should be helpful for other developers!
  • UIHostingConfiguration can cause UICollectionViewRecursion

    Rotating a particular screen in one of my iPhone apps from portait to landscape resulted in a half black screen, a crash, and the following mouthful of an error being logged:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
    reason: 'UICollectionView (...) is stuck in its update/layout loop. This can
    happen for various reasons, including self-sizing views whose preferred 
    attributes are not returning a consistent size. To debug this issue, check the
    Console app for logs in the "UICollectionViewRecursion" category. In particular,
    look for messages about layout invalidations, or changes to properties like
    contentOffset (bounds.origin), bounds.size, frame, etc.
    
    After quite a while of reviewing my collection view’s layout and views, and commenting out different blocks, I uncovered what’s causing the crash. It’s a combination of the following1:
    1. Using the new UIHostingConfiguration from iOS 16 to build collection view cells using SwiftUI.
    2. Using the .frame() modifier anywhere in those SwiftUI views.
    3. Using a flow layout with automatic sizing enabled, and defining a sectionInset.
    In my testing this only crashes on an iPhone, but iPad is fine. It is rather disappointing as I switched from a pure SwiftUI-based grid view to one backed by UICollectionView, so that I can use multi-item selection on iPad, as that’s not yet available through SwiftUI. I did not find an easy fix. Avoid setting a section inset is a quick fix, but might make achieving the layout you want harder. I will see how I go with that, or I might end up going all SwiftUI for this view on iPhone (as multi-item selection isn’t that critical for my use case there) and keep it based on UICollectionView on iPhone.
    1. As confirmed in a simple sample project, and reported to Apple as FB11986452. 
    more…

  • Using Tree-sitter for syntax highlighting in Jekyll

    While exploring a particular rabbit hole for Maparoni, I came across this challenge:

    How can you use a Tree-sitter grammer for syntax highlighting in a Jekyll blog – or, for that matter, just any HTML page by using JavaScript?
    more…

  • Using CoreData in a SPM executable

    Suppose you have a Swift library which uses CoreData and you’d like to use that in a command line tool for something under your control, such as running it on CI or distributing it to colleagues. You could go the route of creating a “Command Line Tool” project in Xcode, which definitely works, but distributing and signing the resulting executable can be a pain. Thanks to recent advances of the Swift Package Manager to support resources and build executables, there seems to be a simpler choice. Spoiler alert: There are hurdles. more…

  • Vapor: Loading resources

    When you’re creating a Vapor app, you might at some stage want to load some resources that you process in your code, e.g., some static data in JSON format that you want to augment. I couldn’t find documentation for it and getting it to work required me to do a detour past the helpful folks in the Vapor discord group, so here’s a quick how to. more…

  • Vapor: Simple automatic deployment using Docker and GitLab CI

    This is a little guide for how to deploy a non-essential API built in Vapor using Docker and GitLab CI on a Linux server. This guide shows how to prepare the project for deployment using Docker, having GitLab CI package up a new version whenever I push, and then have the server pick-up the changes and redeploy automatically. more…

  • Using Carthage in a Catalyst app

    “The process starts by checking a single box in Xcode” and then continues with compile errors. At least if your iOS app is using Carthage to manage its dependencies. Here my notes from working through those in my projects that use Carthage. more…

  • iOS 13 toe-dipping: Multi-window support on iPad

    The code samples from Apple’s WWDC sessions and the sample code for supporting multiple windows, are a bit inconsistent which can make it a bit bumpy to get started. Here is the setup for supporting multiple windows on iPad that worked will in my experimentations so far more…

  • Keyboard shortcuts and the iOS responder chain

    When adding support for keyboard shortcuts, a seasoned iOS developer might raise an eyebrow when noticing that UIKeyCommand takes a selector for an action, but no target. This is because the keyboard commands1 are not send directly to any of your classes, but they instead are passed along the responder chain

    1. More specifically the selectors that fire when the keyboard commands are pressed. 
    more…

  • Good practices for RxSwift-based view models

    Everyone has their own preferred way of structuring their app code. I have grown to like view models and RxSwift. I am not trying to convince anyone to use it with this post, but rather want to share my best practices that took me a few years of using RxSwift to settle on more…

  • Getting push notifications for fastlane errors

    Fastlane is an excellent and essential tool for app developers to automate many of the otherwise time-consuming, tedious tasks. With a simple terminal command you can make run all the steps from compiling and packaging an app, to uploading it to the app stores, updating release notes, uploading the change log on a web page, to basically whatever else you can imagine. These tasks can take a while to run, so you want to know early when they fail. more…

  • Sharing iCloud Drive documents from your app

    I’m building a document-based iOS app for which I want to add sharing and collaboration features. Where possible, I try to use native iOS frameworks and features. When it comes to files, this means using iCloud Drive. This made me investigate how to build sharing and collaboration features on top of iCloud Drive. more…

  • RxSwift in custom views, the clean way

    RxSwift let’s you update your views dynamically in your app in many ways – many of which can get messy over time, as I’ve learned the hard way. The approach that I got used to in order to update views dynamically (and without resorting to crash-prone key-value-observation) was to pass Observables to the views. The views then subscribed to them and cleaning up o their own using a DisposeBag. It worked, but closely coupled the views to RxSwift. RxSwift has a much cleaner way for doing this – a Binder. more…

  • Importing app module in unit test fails to compile

    For months, CI and Xcode unit tests for a project at work have been plaguing me with a strange issue: At times and without obvious cause, some unit tests started failing to compile, saying that the classes of the app’s module could not get found – lots of Use of undeclared type and Use of unresolved identifier errors. more…

  • Lessons from converting complex submodules to Cocoapods

    I have recently converted two fairly large iOS libraries (written in a mixture of Objective-C and Swift) from a plain git submodule to a set of dynamic frameworks that can be used as Cocoapods. The process was quite tedious, so here’s a random collection of hurdles that had to be crossed. more…

  • Upload rejected due to CFBundleResourceSpecification

    When submitting a new build to the App Store today, iTunes Connect greated me with a error that the build was rejected due to the use of CFBundleResourceSpecification in the Info.plist file. more…

  • Custom transitions for pushing container view controllers

    A common user interface paradigm in TripGo is to provide a list view with an associated map view. On the iPhone we display them on top of each other, while on the iPad we display them next to each other, which we have achieved by using separate storyboards for both devices. However, maintaining two storyboards has a number of downside and with iOS 9 around the corner, that adds the ability to show apps side-by-side, it is time to kiss goodbye to this approach. After briefly investigating the now more powerful UISplitViewController, we are now saying “Hello” to the magic world of trait collections, custom transitions and container views! more…

  • Drawing multi-coloured lines on an MKMapView

    MKMapView is a great toolkit to customise and add a variety of things to a map on iOS, but one thing that I found lacking was an easy way to draw a multi-coloured line. Specifically, I wanted a way to draw a border around a line but the standard MKPolylineView component does not allow doing that. As digging around on GitHub, Google and StackOverflow did not yield any existing projects that allow doing so, I have a look for how to do it and the result is ASPolylineView - a simple drop-in replacement for an MKPolylineView. more…

  • iOS, AddressBook framework and GCD

    For my latest iOS app I was working on an autocompletion field that hooks into the user’s phone address book and calendar. This is a great way for making the user feel at home in your app and makes your app feel part of the phone. At first I tapped into the AddressBook and EventKit frameworks on the main thread while the user is typing, but that lead to a rather unresponsive user interface since both the AddressBook and EventKit frameworks can take a short while to access the contents. So, that work should be done on a background thread, while keeping the main thread available to respond to the user’s typing. more…