Say you have the name of an application, Mail.app
, how do you programmatically obtain com.apple.mail
from the application name?
A bundle ID or bundle identifier is a unique identifier of an app in Apple's ecosystem. It means that no two apps can have the same bundle ID. A bundle identifier lets macOS recognize any updates to your app. It is used in validating the application signature.
A bundle ID or bundle identifier uniquely identifies an application in Apple's ecosystem. This means that no two applications can have the same bundle identifier. To avoid conflicts, Apple encourages developers to use reverse domain name notation for choosing an application's bundle identifier.
The following method will return an application's Bundle Identifier for a named application:
- (NSString *) bundleIdentifierForApplicationName:(NSString *)appName
{
NSWorkspace * workspace = [NSWorkspace sharedWorkspace];
NSString * appPath = [workspace fullPathForApplication:appName];
if (appPath) {
NSBundle * appBundle = [NSBundle bundleWithPath:appPath];
return [appBundle bundleIdentifier];
}
return nil;
}
For Mail you can call the method like so:
NSString * appID = [self bundleIdentifierForApplicationName:@"Mail"];
appID
now contains com.apple.mail
import AppKit
func bundleIdentifier(forAppName appName: String) -> String? {
let workspace = NSWorkspace.shared
let appPath = workspace.fullPath(forApplication: appName)
if let appPath = appPath {
let appBundle = Bundle(path: appPath)
return appBundle?.bundleIdentifier
}
return nil
}
// For Mail you can call the method like so:
let appID = bundleIdentifier(forAppName: "Mail")
The fullPathForApplication:
/ fullPath(forApplication:)
method has been deprecated in macOS 10.15 - it is unclear what the answer is going forward.
Expanding on Francesco Germinara's answer in Swift 4, macOS 10.13.2:
extension Bundle {
class func bundleIDFor(appNamed appName: String) -> String? {
if let appPath = NSWorkspace.shared.fullPath(forApplication: appName) {
if let itsBundle = Bundle(path: appPath) { // < in my build this condition fails if we're looking for the ID of the app we're running...
if let itsID = itsBundle.bundleIdentifier {
return itsID
}
} else {
//Attempt to get the current running app.
//This is probably too simplistic a catch for every single possibility
if let ownID = Bundle.main.bundleIdentifier {
return ownID
}
}
}
return nil
}
}
Placing it your Swift project, you can call it like this:
let id = Bundle.bundleIDFor(appNamed: "Mail.app")
or
let id = Bundle.bundleIDFor(appNamed: "Mail")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With