在Swift中获取应用程序名称

Kaa*_*att 49 cocoa swift

如何在Swift中获取应用程序名称?

谷歌搜索给了我这个:

[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
Run Code Online (Sandbox Code Playgroud)

我把它改成了斯威夫特; 错误 - 方法不存在:

NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")
Run Code Online (Sandbox Code Playgroud)

Gri*_*mxn 99

这应该工作:

NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
Run Code Online (Sandbox Code Playgroud)

infoDictionary声明为一个var infoDictionary: [NSObject : AnyObject]!所以你必须打开它,将它作为一个Swift字典(而不是使用objectForKey)访问它,并且,结果是一个AnyObject,抛出它.

更新Swift 3(Xcode 8 beta 2)

总是更好地使用常量:

Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String
Run Code Online (Sandbox Code Playgroud)

  • `如!String`现在 (9认同)
  • 我是唯一一个认为具有讽刺意味的Full Decent推荐力量演员吗? (2认同)
  • CFBundleName 可能并不总是显示给用户的应用程序的名称。请参阅下面我的答案,了解如何获取主屏幕图标下显示的应用程序名称。 (2认同)

Vad*_*vin 26

我相信这个解决方案更优雅.更重要的object(forInfoDictionaryKey:),苹果鼓励使用:

"使用此方法优于其他访问方法,因为它在一个可用时返回键的本地化值."

extension Bundle {
    var displayName: String? {
        return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
    }
}
Run Code Online (Sandbox Code Playgroud)

访问捆绑显示名称:

if let displayName = Bundle.main.displayName {
    print(displayName)
}
Run Code Online (Sandbox Code Playgroud)

  • 它应该是`CFBundleDisplayName`.但如果不可用,它应该回到`CFBundleName`.请参阅下面的答案. (2认同)

Mar*_*rný 13

我创建了一个简单的扩展来获取主屏幕上图标下显示的应用名称.

默认情况下,应用仅CFBundleName设置.但是,某些应用程序设置CFBundleDisplayName (用户可见的包名称)以更改应用程序图标下的标题.通常情况下添加空格,例如,包名称"ExampleApp"可以将包显示名称设置为"Example App".

extension Bundle {
    // Name of the app - title under the icon.
    var displayName: String? {
            return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
                object(forInfoDictionaryKey: "CFBundleName") as? String
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let appName = Bundle.main.displayName
Run Code Online (Sandbox Code Playgroud)

  • 这应该是首选答案.它不仅可以处理这两种情况,而且还可以在没有强制包装的情况下进行处理,这种情况永远不会出现在示例代码中. (2认同)

Sha*_* Ye 8

斯威夫特4

let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String


Abd*_*ich 7

Swift 4.2中的答案相同

extension Bundle {
    static func appName() -> String {
        guard let dictionary = Bundle.main.infoDictionary else {
            return ""
        }
        if let version : String = dictionary["CFBundleName"] as? String {
            return version
        } else {
            return ""
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以像下面一样使用它

let appName = Bundle.appName()
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)


小智 6

简单方法:

let appName = NSBundle.mainBundle().infoDictionary?[kCFBundleNameKey as String] as? String
Run Code Online (Sandbox Code Playgroud)

方便的方式:

extension NSBundle {
    class func mainInfoDictionary(key: CFString) -> String? {
        return self.mainBundle().infoDictionary?[key as String] as? String
    }
}
print(NSBundle.mainInfoDictionary(kCFBundleNameKey))
Run Code Online (Sandbox Code Playgroud)

kCFBundleNameKey - 标准Info.plist键,请参阅CFBundle中的更多内容


Mec*_*cki 6

  1. 所有刚刚返回的答案CFBundleName通常不会返回用户期望的名称,就好像捆绑包有一个CFBundleDisplayName,然后 Finder、系统框架和大多数其他应用程序都会显示此键。

  2. 大多数答案只是直接访问信息字典,但信息字典可以通过字符串文件本地化,当直接访问它们时,这种本地化也会被忽略,因此可能会再次返回错误的名称,因为 Finder 将显示本地化的名称。

  3. 虽然在文件CFBundleDisplayName中是可选的,但实际上不是,但如果您忘记添加它,系统中不会出现任何问题,因此您的信息字典已损坏,但大多数用户可能永远不会注意到,在这种情况下,大多数答案的代码可能根本不返回任何有意义的东西。Info.plistCFBundleName

这是我的解决方案(Swift 3):

private
func stripFileExtension ( _ filename: String ) -> String {
    var components = filename.components(separatedBy: ".")
    guard components.count > 1 else { return filename }
    components.removeLast()
    return components.joined(separator: ".")
}

func nameOfApp ( ) -> String {
    let bundle = Bundle.main
    if let name =  bundle.object(forInfoDictionaryKey: "CFBundleDisplayName")
        ?? bundle.object(forInfoDictionaryKey: kCFBundleNameKey as String),
        let stringName = name as? String
        { return stringName }

    let bundleURL = bundle.bundleURL
    let filename = bundleURL.lastPathComponent
    return stripFileExtension(filename)
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案如何更好?

  1. 它将首先检查,如果不存在则CFBundleDisplayName仅回退到。CFBundleName

  2. object()方法始终对信息字典的本地化版本进行操作,因此如果本地化存在,则会自动使用它。

  3. 如果字典中也不CFBundleDisplayName存在CFBundleName,则代码将回退到仅使用磁盘上的捆绑文件名而不带扩展名(因此“My Cool App.app”将是“My Cool App”),这是一个回退,以便此函数将一去不复返nil


小智 6

let appDisplayName = Bundle.main.infoDictionary?["CFBundleName"] as? String
Run Code Online (Sandbox Code Playgroud)

它是可选的,因此请将其放在 if let 或 Guard 语句中。


Pra*_*tik 5

// 返回应用名称

public static var appDisplayName: String? {
    if let bundleDisplayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String {
        return bundleDisplayName
    } else if let bundleName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String {
        return bundleName
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)