如何从 Cocoa 中的应用程序名称中获取 Bundle Identifier?

Posted

技术标签:

【中文标题】如何从 Cocoa 中的应用程序名称中获取 Bundle Identifier?【英文标题】:How do you get the Bundle Identifier from an application's name in Cocoa? 【发布时间】:2012-02-23 06:38:05 【问题描述】:

假设您有一个应用程序的名称Mail.app,您如何以编程方式从应用程序名称中获取com.apple.mail

【问题讨论】:

【参考方案1】:

以下方法将为命名应用程序返回应用程序的包标识符:

- (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; 

对于邮件,您可以像这样调用该方法:

NSString * appID = [self bundleIdentifierForApplicationName:@"Mail"];

appID 现在包含 com.apple.mail

斯威夫特 5.1

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")

弃用

fullPathForApplication: / fullPath(forApplication:) 方法已在 macOS 10.15 中弃用 - 尚不清楚未来的答案是什么。

【讨论】:

谢谢!这正是我一直在寻找的。但是,在我的测试中,Mail.app 也可以正常工作,这并不奇怪,因为苹果在其许多文档中都表示.app 是可选的。但是,MAil.appMail.APP 似乎也可以工作,所以我想也许应用程序名称也不完全区分大小写。 好的,我会删除另外说明的注释 请注意,fullPathForApplication:appName 在 macOS 10.15 中已被软性弃用。我找不到任何替代方案,所以我猜苹果希望我们只使用捆绑标识符...... 谢谢 Sindre Sorhus,我已经添加了剥夺通知。【参考方案2】:

在 Swift 4、macOS 10.13.2 中扩展 Francesco Germinara 的答案:

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
    

将它放在你的 Swift 项目中,你可以这样称呼它:

let id = Bundle.bundleIDFor(appNamed: "Mail.app")

let id = Bundle.bundleIDFor(appNamed: "Mail")

【讨论】:

【参考方案3】:

它是 Contents/Info.plist 中键 CFBundleIdentifier 的值

【讨论】:

除此之外,应用程序的“Contents”文件夹通常可以在 /Applications//.app/Contents/ 中找到【参考方案4】:

这是一个可能的快速实现

func bundleIdentifierForApplicationName(appName : String) -> String

    var workspace = NSWorkspace.sharedWorkspace()
    var appPath : String = workspace.fullPathForApplication(appName)
    if (appPath != "") 
        var appBundle : NSBundle = NSBundle(path:appPath)
     return appBundle.bundleIdentifier
    
   return ""

【讨论】:

以上是关于如何从 Cocoa 中的应用程序名称中获取 Bundle Identifier?的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa/Swift:遍历路径中文件夹的名称

如何从 Cocoa 中的窗口控制器获取当前的第一响应者?

如何解决 Cocoa touch 框架中的符号名称冲突

如何从 rac_sequence、reactive cocoa、ios 获取项目

我如何在 Cocoa 中获取应用程序菜单

Cocoa/如何在应用程序委托中获取对当前窗口的 contentViewController 的引用?