Adding Swift Package Manager Support to a Legacy Objective-C Project

I recently needed to add Swift Package Manager support to a legacy package that one of my projects was using. The package was originally distributed with CocoaPods. The primary reason for migrating from CocoaPods to SPM is that CocoaPods entered maintenance mode a few months ago. Removing it will future-proof our projects and allow us to use the latest features, such as the buildable folders introduced in Xcode 16. Assumptions Since this was an internal package, I did not need to maintain CocoaPods support. The goal was to replace it entirely with SPM. It is certainly possible to keep both, but that would require some additional work. The project I was working on is considered legacy; no one has touched it in about six years. Once this task is complete, I hope no one will need to update it for another half-dozen years. This allowed me to take some shortcuts, like integrating a third-party dependency directly into the codebase instead of spending time updating it to the latest version. All internal dependencies of your framework already support SPM. With that said, let’s get started. ...

June 3, 2025 · Bartosz Kunat

Getting Back Up to Speed with Objective-C in 2025

I’ve mostly moved away from using Objective-C over the years. While it still appears in some of the projects I work on, it’s been quite some time since I last had to work on a feature written entirely in Objective-C. These days, I typically encounter it when integrating a new feature written in Swift into an older codebase. Recently, however, I needed to brush up on Objective-C for a job I was interviewing for. ...

April 3, 2025 · Bartosz Kunat

Region-Specific Language Control: Implementing Forced Localization in iOS Apps

My current project has a single target and multiple schemes. Each scheme represents the same app for different countries/regions. It’s essentially the same application with minor adjustments made for each of the supported jurisdictions. In Xcode projects, you define supported languages at the project level (not scheme level). Because of this structure, each app variant inherits the same language settings. My task was to force each app variant to support only the language for the region it was released in. The French app should only support French, no matter what the user’s device language is set to, and so on. This decision was made because large portions of the app are web-based and only supported a single language. ...

April 2, 2025 · Bartosz Kunat

Creating a New Objective-C Project in Xcode 16

Update: 26/03/25 It looks like Objective-C is still an option in the default iOS project template. You can access it after setting the Interface to “Storyboard”. I hadn’t realized these dropdown menus were interconnected. All credit goes to Douglas for spotting this! tl;dr use macOS → Application → Game or Command Line Tool Recently I wanted to refresh my memory on Objective-C. My first thought was to open Xcode, create a new project with language set to Objective-C and play with it. To my surprise, none of the iOS Application project templates allow you to select any other language than Swift. ...

March 25, 2025 · Bartosz Kunat

Temporarily Disable SwiftLint plugin in Swift Packages

I’ve noticed that the SwiftLint plugin can add up to 30 seconds to incremental build times. In my case, it nearly doubled the average incremental build time! Since there’s no straightforward way to disable SwiftLint across all local packages in a project, I decided on the simplest solution: automating the process of temporarily commenting out SwiftLint from the dependencies list. In my projects, to ensure the SwiftLint plugin is automatically added to all package targets, I append the following code to each Swift package manifest: ...

February 11, 2025 · Bartosz Kunat

Create a Safari Extension to Extract Article Content

In this article, I’ll show you how to access a web page’s content, alter it using JavaScript, and display it using your Safari extension’s UI. Specifically, I’ll demonstrate how to display an article’s content in a popover. I often use Large Language Models (LLMs) to summarize articles when I’m unsure if they’re worth reading. Without the extension we’re about to build, I’d need to manually trigger Safari’s reader mode (⌘ + ⇧ + R), copy all content, and paste it into Claude or ChatGPT. This extension is a handy tool that reduces friction! ...

December 18, 2024 · Bartosz Kunat

Xcode: Missing Package Product (local package)

When adding a local Swift package to your Xcode project, you might encounter the following error: Missing package product `PACKAGE_NAME` The issue often occurs when the package you’re trying to add is already open in Xcode. To resolve: Close the package in Xcode. Close your main project. Reopen your main project. I’m not sure what might be causing this issue or why reopening the project is required (a clean build won’t do). ...

June 24, 2024 · Bartosz Kunat