获取 Swift 中的应用名称

Get App Name in Swift

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

谷歌搜索给了我这个:

[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];

我把它转换成了Swift;错误 - 方法不存在:

NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")

试试这个,

let bundleID = NSBundle.mainBundle().bundleIdentifier

这应该更像您要查找的内容:

let infoDictionary: NSDictionary = NSBundle.mainBundle().infoDictionary as NSDictionary!
let appName: NSString = infoDictionary.objectForKey("CFBundleName") as NSString

NSLog("Name \(appName)")

可能还有更好的方法来做到这一点,但至少 returns 在我非常有限的测试中应用名称是正确的...

这应该有效:

NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String

infoDictionary 被声明为 var infoDictionary: [NSObject : AnyObject]! 所以你必须打开它,作为 Swift 字典访问它(而不是使用 objectForKey),并且,作为结果是 AnyObject,施放它。

更新Swift 3 (Xcode 8 beta 2)

最好也尽可能使用常量(和可选值):

Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String
let bundleInfoDict: NSDictionary = NSBundle.mainBundle().infoDictionary!
let appName = bundleInfoDict["CFBundleName"] as String

简单的方法:

let appName = NSBundle.mainBundle().infoDictionary?[kCFBundleNameKey as String] as? String

方便的方法:

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

kCFBundleNameKey – 标准 Info.plist 键,在 CFBundle

中查看更多信息

这个非常适合我

let appName = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleDisplayName") as! String

我相信这个解决方案更优雅。更何况用object(forInfoDictionaryKey:)就是encouraged by Apple:

"Use of this method is preferred over other access methods because it returns the localized value of a key when one is available."

extension Bundle {
    var displayName: String? {
        return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
    }
}

访问包显示名称:

if let displayName = Bundle.main.displayName {
    print(displayName)
}
  1. 所有仅 return CFBundleName 的答案通常不会 return 用户期望的名称,就好像 bundle 有一个 CFBundleDisplayName,然后此密钥由 Finder、系统框架和大多数其他应用程序显示。

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

  3. 虽然 CFBundleDisplayNameInfo.plist 文件中是可选的,但 CFBundleName 实际上不是,但是如果您忘记添加它,您的系统不会出现任何问题,所以你有一个损坏的信息字典,但大多数用户可能永远不会注意到,在这种情况下,代码大多数答案可能 return 根本没有任何意义。

这是我的解决方案 (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)
}

这个解决方案有哪些更好的地方?

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

  2. object() 方法始终在信息字典的本地化版本上运行,因此如果存在本地化版本,将自动使用它。

  3. 如果 CFBundleDisplayNameCFBundleName 都不存在于字典中,代码回退到只使用磁盘上没有扩展名的包文件名(所以 "My Cool App.app"将是 "My Cool App"),这是一个回退,因此该函数永远不会 return nil.

试试这个:

extension Bundle {
    var displayName: String {
        let name = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
        return name ?? object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
    }
}

我创建了一个简单的扩展来获取显示在主屏幕图标下方的应用程序名称。

默认情况下,应用只有 CFBundleName 设置。但是,某些应用程序设置 CFBundleDisplayName (捆绑包的 user-visible 名称) 以更改应用程序图标下的标题。通常会添加空格,例如捆绑名称 "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
    }
}

用法:

let appName = Bundle.main.displayName

Swift 4

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

// Returns 应用名称

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
}

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

你可以像下面这样使用它

let appName = Bundle.appName()

希望这对您有所帮助:)

let appDisplayName = Bundle.main.infoDictionary?["CFBundleName"] as? String

它是可选的,所以把它放在 if let 或 guard 语句中。

这就是我在 Xcode 11.0 和 Swift 5

中使用的方法
 let bundleID = Bundle.main.bundleIdentifier
 let bundleInfoDict: NSDictionary = Bundle.main.infoDictionary! as NSDictionary
 let appName = bundleInfoDict["CFBundleName"] as! String
 print(bundleID!)
 print(appName)

这个在 Swift 4.2

对我有用
guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
   return version
} else {
   return ""
}

对于swift5,iOS13*

如前所述,它是可选的,因此将其放在 guard 语句中。我使用一个结构来做到这一点:

struct Model {
    struct ProgVariablen{
        static var appBundleName:String {
            get {guard Bundle.main.infoDictionary != nil else {return ""}
                return Bundle.main.infoDictionary!["CFBundleName"] as! String
            }//end get
        }//end computed property
        static var appBundleShortVersion:String {
            get {guard Bundle.main.infoDictionary != nil else {return ""}
                return Bundle.main.infoDictionary ["CFBundleShortVersionString"] as! String
            }//end get
        }//end computed property
        static var appBundleBuild:String {
            get {guard Bundle.main.infoDictionary != nil else {return ""}
                return Bundle.main.infoDictionary["CFBundleVersion"] as! String
        }//end get
    }//end computed property

    //initialsieren der Variablen
    init(
         appBundleName:String,
         appBundleShortVersion:String,
         appBundleBuild:String,
         )
    {
        // do here nothing for 'let'
        // do here nothing for 'computed properties'
        // your other ‘var’ are here like:
        // ProgVariablen.var1 = var1
    }//end init
    }//end struct ProgVariablen
}//end struct Model

用法:

print("Model.ProgVariablen.appBundleName: '\(Model.ProgVariablen.appBundleName)'")