在Swift中获取应用程序名称

时间:2015-01-31 17:24:21

标签: cocoa swift

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

谷歌搜索给了我这个:

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

我将它转换为Swift;错误 - 方法不存在:

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

17 个答案:

答案 0 :(得分:95)

这应该有效:

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

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

更新Swift 3(Xcode 8 beta 2)

最好尽可能使用常量:

AnyObject

答案 1 :(得分:24)

我相信这个解决方案更优雅。更重要的是,使用object(forInfoDictionaryKey:)encouraged by Apple

  

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

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

访问捆绑显示名称:

if let displayName = Bundle.main.displayName {
    print(displayName)
}

答案 2 :(得分:9)

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

默认情况下,应用只设置CFBundleName。但是,有些应用会设置CFBundleDisplayName (用户可见的捆绑名称)以更改应用图标下的标题。通常情况下,添加空格,例如捆绑名称" ExampleApp"可以将包显示名称设置为"示例应用"。

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

答案 3 :(得分:7)

Swift 4

CommandParameter

答案 4 :(得分:6)

简单的方法:

    var backgroundColour = UIColor.BlueColor()
    var foregroundColour = MyColours.ORANGE
    var button = UIButton( type: UIButtonType.System ) as UIButton

    button.frame = CGRectMake( 100, 100, 200, 50 )
    button.backgroundColor = backgroundColour
    button.setTitleColor( foregroundColour, forState: .Normal )
    button.setTitle( "Some Button", forState: UIControlState.Normal )

    myView.addSubview( button )

方便的方式:

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

kCFBundleNameKey - 标准Info.plist键,详见 CFBundle

答案 5 :(得分:5)

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

希望这会有所帮助:)

答案 6 :(得分:2)

这应该更符合您的要求:

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

NSLog("Name \(appName)")

可能还有更好的方法可以做到这一点,但它至少会在我非常有限的测试中正确地返回应用名称......

答案 7 :(得分:2)

此版本在 Swift 4.2

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

答案 8 :(得分:2)

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

它是可选的,因此在let或guard语句中放入。

答案 9 :(得分:2)

//返回应用名称

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
}

答案 10 :(得分:2)

试试这个:

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

答案 11 :(得分:2)

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

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

  3. 虽然CFBundleDisplayName文件中的Info.plist是可选的,但CFBundleName实际上并非如此,但如果您忘记添加它,系统中什么都不会中断,所以你有一个腐败的信息词典,但大多数用户可能永远不会注意到,在这种情况下,大多数答案的代码可能根本不会返回任何有意义的。

  4. 这是我的解决方案(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. 如果字典中既不存在CFBundleDisplayName也不存在CFBundleName,则代码将回退到仅使用磁盘上的包文件名而不使用扩展名(所以" My Cool App.app& #34;将是"我的酷应用程序"),这是一个后备,以便此函数永远不会返回nil

答案 12 :(得分:1)

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

答案 13 :(得分:1)

这就是在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)

答案 14 :(得分:0)

这个对我来说非常适合

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

答案 15 :(得分:0)

试试这个,

let bundleID = NSBundle.mainBundle().bundleIdentifier

答案 16 :(得分:0)

对于Swift 5,iOS 13 *

如前所述,它是可选的,因此将其放在保护声明中。我使用结构体来做到这一点:

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