AboutWriting

Script to Update App Logos Automatically on macOS

In order to update the icons of apps automatically after they are updated to a new version, you can use the NSWorkspace class to monitor for changes in the app's bundle and then trigger your icon updating code.

Here's some sample Swift code that can be used to automatically update the ICNS icon for an app on macOS:

import Cocoa

class IconUpdater {
    let appPath = "/path/to/your/app.app"
    let iconPath = "/path/to/your/icon.icns"
    let workspace = NSWorkspace.shared
    var observer: Any?

    init() {
        observer = workspace.notificationCenter.addObserver(forName: NSWorkspace.didRenameFileNotification, object: nil, queue: nil) { [weak self] notification in
            guard let userInfo = notification.userInfo,
                let oldPath = userInfo["NSFilePath"] as? String,
                let newPath = userInfo["NSNewFilePath"] as? String,
                oldPath == self?.appPath,
                newPath.hasSuffix(".app") else { return }
            self?.updateIcon()
        }
    }

    deinit {
        if let observer = observer {
            NSWorkspace.shared.notificationCenter.removeObserver(observer)
        }
    }

    func updateIcon() {
        // Get the current app bundle
        let appBundle = NSBundle(path: appPath)

        // Get the current icon file
        let currentIconPath = appBundle?.path(forResource: "appIcon", ofType: "icns")

        // Remove the current icon file
        try? FileManager.default.removeItem(atPath: currentIconPath!)

        // Copy the new icon file to the app bundle
        try? FileManager.default.copyItem(atPath: iconPath, toPath: currentIconPath!)
    }
}

let iconUpdater = IconUpdater()

This code creates an instance of the IconUpdater class, which sets up an observer for the NSWorkspaceDidRenameFileNotification notification. The observer checks if the file that was renamed is the app bundle and if it has the ".app" extension, and if so, it calls the updateIcon() function. The updateIcon() function is the same as the one in my previous answer and updates the icon.

It will update the icon of the app bundle located at appPath with the icon located at iconPath.

The directory where you place the iconUpdater.swift file can be anywhere on your system, as long as it is accessible by your app. You can place it in the same directory as your app's executable file, or in a subdirectory within your app's bundle.

swift /path/to/iconUpdater.swift