# SwiftDefaultApps: macOS default handler control

> SwiftDefaultApps is a macOS preference pane and optional CLI for viewing and changing default handlers for URL schemes and file types through LaunchServices. Its deprecated APIs and custom license require careful review before adoption.

**Lord-Kamina/SwiftDefaultApps** — Replacement for RCDefaultApps, written in Swift.

- Repository: https://github.com/Lord-Kamina/SwiftDefaultApps
- Stars: 1,753 · Forks: 72
- Language: Swift
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/lord-kamina-swiftdefaultapps

## Why SwiftDefaultApps Exists

SwiftDefaultApps is a macOS preference pane intended to replace RCDefaultApps after that project stopped working in macOS 10.12 because it depended on deprecated Objective-C garbage collection. The author also says that creating SwiftDefaultApps was a way to learn Swift.

Its operational target is narrower than general macOS application management. The pane presents default application associations for URI schemes and file types, with file types represented by UTIs. It is intended for users who need to inspect or change these LaunchServices associations directly, rather than only opening the relevant extension panel in macOS System Settings. The optional CLI can be useful when the pane is not the preferred interface, although the README does not provide a complete command-by-command CLI tutorial.

The project should not be confused with a mechanism for changing every application permission. Its documented scope is default handler selection. URI schemes include links such as custom protocols, while file types cover formats recognized by macOS. Candidate applications are supplied by LaunchServices, and the pane lets the user select a listed handler, the bundled Do Nothing application, or another application through the Other option.

## LaunchServices Data Flow and Selection Rules

The core mechanism is macOS LaunchServices. According to the README, selecting a URI scheme or file type causes SwiftDefaultApps to request the valid applications available for each LaunchServices role. The data is generated by LaunchServices itself, so the project does not maintain its own independent catalog of every application that can handle every format.

The read and write path relies on calls identified as `LSSetDefaultHandlerForURLScheme` and `LSSetDefaultRoleHandlerForContentType`. The README also mentions the private `_LSCopySchemesAndHandlerURLs` SPI. These calls still worked when the project was last verified, but all three are a material adoption constraint. The two public-looking handler calls are described by the project as deprecated, while the underscored copy call is explicitly private. A future macOS release could therefore change behavior without this repository supplying a stable public API migration.

The Other option can select an application outside the candidate list, but the README warns that only valid associations persist. LaunchServices checks for invalid or stale associations and removes them. This makes the feature a presentation of what macOS accepts, not an unconditional override of the operating system's association rules.

Do Nothing registers the selected item with a dummy application. The application prints the URI scheme or UTI that launched it and exits. It is also the default handler for custom schemes created through the pane, which creates an important removal constraint described later.

## Installing the Preference Pane

The README offers a release download and a Homebrew installation route. For the release route, download the latest `.prefpane` from the repository's Releases page, open it, and accept the macOS installation prompt. To remove the pane, use Ctrl+Click on its icon and remove it, or move the `.prefpane` file to the Trash.

Homebrew provides a shorter installation path for users who already manage packages with the tool. After installation, Spotlight should open `SwiftDefaultApps.prefpane` into System Preferences, where its icon appears at the bottom of the icon list.

```bash
brew install swiftdefaultappsprefpane
```

This command installs the published preference pane package. It does not document whether a separate CLI package is installed, so users who need `swda` should verify its availability rather than assume the preference pane command includes it.

## Apple Silicon Source Build and Architecture Check

The README identifies a concrete Apple Silicon failure mode. Releases published before Apple Silicon are `x86_64`-only, while macOS hosts third-party preference panes in `legacyLoader-arm64`. An `arm64` process cannot load the `x86_64` bundle, and Rosetta translates whole processes rather than individual plug-ins. On such a system, the preference pane does not appear in System Settings and emits no visible error.

Check the installed executable architecture first. If `lipo` reports `x86_64`, rebuild the project from source so it produces both `arm64` and `x86_64`.

```bash
lipo -info ~/Library/PreferencePanes/SwiftDefaultApps.prefpane/Contents/MacOS/SwiftDefaultApps
```

The documented source-build sequence clones the repository, enters it, and runs `build.sh`. The script produces a universal binary, signs it with the first `Developer ID Application` identity found in the keychain, or falls back to an ad-hoc signature for local use. It also installs the result into `~/Library/PreferencePanes`, moving an earlier installation to `backups/` instead of deleting it.

```bash
git clone https://github.com/Lord-Kamina/SwiftDefaultApps.git
cd SwiftDefaultApps
./build.sh
```

Use `./build.sh --no-install` to build and sign without installing, and `./build.sh --cli` to include the `swda` command-line tool. The README also documents `SIGN_ID="-"` for a forced ad-hoc signature, `ARCH="arm64"` for a narrower build, and `DEPLOY_TARGET="12.0"` as the minimum macOS version. No architecture settings are needed in the Xcode projects because they use `ARCHS_STANDARD`.

## Preparing Do Nothing for Default Associations

The Do Nothing application must be launched once before it can be selected reliably in the preference pane. The documented procedure checks both the system-level and user-level preference pane locations, removes the quarantine attribute, and opens the application.

```bash
appDir="/Library/PreferencePanes/SwiftDefaultApps.prefPane/Contents/Resources/ThisAppDoesNothing.app"

if ! [[ -d "$appDir" ]]; then appDir="$HOME/$appDir"; fi

xattr -d com.apple.quarantine "$appDir"
open "$appDir"
```

The README's terminal procedure includes the exact application paths and fallback used when the system-level directory is absent. It labels the quarantine step as `Remove quanrantine flag`, but the command itself uses the standard `com.apple.quarantine` attribute. After `open` completes, the pane should be able to offer Do Nothing as a handler.

There is a deeper association consequence. Custom URI schemes added through the pane are associated with Do Nothing by default. Because the dummy application remains a valid handler while SwiftDefaultApps is installed, macOS may continue to discover a valid association after the custom scheme has been removed from the pane. The README says removal through the interface is not available or necessary, but notes that uninstalling and reinstalling may be required to clear an unwanted custom scheme.

## Limits, Maintenance, and the RCDefaultApps Difference

The clearest limitation is platform dependence. SwiftDefaultApps manipulates LaunchServices state and relies on deprecated or private interfaces. The README reports that the handler reads and writes worked when last verified, but it does not describe compatibility testing across current macOS releases or promise a public API replacement. Its usefulness on a future release cannot be established from the repository documentation.

RCDefaultApps is the project that motivated SwiftDefaultApps after it stopped working in macOS 10.12 due to deprecation of Objective-C garbage collection. SwiftDefaultApps is written in Swift and uses macOS 12.0 as its deployment target.

Maintenance should be assessed from repository history rather than release frequency alone. The repository is not archived, and the last push was on 2026-10-05. The listed releases are older: `v2.0.1` on 2019-07-29, `v2.0.0` on 2019-06-19, and `v1.1.3` on 2018-11-15. A recent push indicates repository work, but the README does not document a release plan, support matrix, migration to Apple's replacement APIs, or a rollback policy.

The license is also not a standard GitHub classification. The repository contains a custom `LICENSE` file, but its terms are not reproduced in the README. Users should read that file directly before redistribution or organizational use. The project is source-available in the ordinary repository sense, but the available documentation does not support a more specific statement about redistribution, warranty, or liability.

## Finding a File Type UTI

When a specific file type must be located, the README gives a metadata query that reads the content type, content type tree, and kind for a file. Replace `my_song.mp3` with the path of the file being inspected.

```bash
mdls -name kMDItemContentType -name kMDItemContentTypeTree -name kMDItemKind my_song.mp3
```

The returned metadata values can be used to identify the UTI shown by the preference pane. This is a diagnostic workflow rather than a handler change. The repository does not document a command for setting a default directly from the CLI, so the README's first complete user path remains the preference pane.

## Conclusion

SwiftDefaultApps fits users who still need direct control over macOS URL scheme and file type associations and can accept its deprecated LaunchServices dependency. It is a poor fit for users who require a currently documented replacement API path or need clear license permissions. Before installation, verify that the pane appears in the targeted macOS release, inspect the custom LICENSE file, and decide whether the preference pane or `swda` workflow is required.

## FAQ

### Can SwiftDefaultApps change default handlers on Apple Silicon?

The README says an older `x86_64` preference pane may not appear in System Settings on Apple Silicon because macOS hosts the pane through `legacyLoader-arm64`. Rebuilding with `./build.sh` produces a universal `arm64` and `x86_64` binary according to the documentation.

### How do I install SwiftDefaultApps with Homebrew?

Run `brew install swiftdefaultappsprefpane`, then open `SwiftDefaultApps.prefpane` with Spotlight. The README says the pane opens in System Preferences and appears at the bottom of the icons.

### Why can an unwanted custom URI scheme remain associated with Do Nothing?

The README says custom schemes are associated with Do Nothing by default. Because that application remains available as a valid handler while SwiftDefaultApps is installed, the scheme may not be removable without uninstalling and reinstalling the preference pane.

## Sources

- [Issues](https://github.com/Lord-Kamina/SwiftDefaultApps/issues)
- [Lord-Kamina/SwiftDefaultApps on GitHub](https://github.com/Lord-Kamina/SwiftDefaultApps)
- [README](https://github.com/Lord-Kamina/SwiftDefaultApps/blob/master/README.md)
- [Releases](https://github.com/Lord-Kamina/SwiftDefaultApps/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lord-kamina-swiftdefaultapps
