我该如何在Swift中获取应用程序的名称?
谷歌搜索给了我这个:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
我将其转换为Swift;错误 - 方法不存在:
NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")
这应该可以工作:
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
我认为这个解决方案更加优雅。此外,使用object(forInfoDictionaryKey:)
方法得到的结果是被苹果公司所推荐的:
"使用该方法比其他访问方法更好,因为当存在本地化的键值对时,它会返回本地化的值。"
extension Bundle {
var displayName: String? {
return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
}
}
访问捆绑包显示名称:
if let displayName = Bundle.main.displayName {
print(displayName)
}
CFBundleDisplayName
是正确值的引用:“iPhone主屏幕上的应用程序名称来自CFBundleDisplayName(或“Bundle display name”,即Xcode中的可读字符串)”。 - Vadim BulavinCFBundleDisplayName
。但是如果没有可用的,就应该退而求其次使用CFBundleName
。请参阅下面我的答案。 - Marián Černýextension Bundle {
/// Application name shown under the application icon.
var applicationName: String? {
object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
object(forInfoDictionaryKey: "CFBundleName") as? String
}
}
使用方法:
let appName = Bundle.main.applicationName
同样的答案在 Swift 4.2 中
extension Bundle {
class var applicationName: String {
if let displayName: String = Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String {
return displayName
} else if let name: String = Bundle.main.infoDictionary?["CFBundleName"] as? String {
return name
}
return "No Name Found"
}
}
你可以像下面这样使用它
Bundle.applicationName
或者,另一种方法是避免使用静态或类方法或属性,而是添加到实例级别。
extension Bundle {
var applicationName: String {
if let displayName: String = self.infoDictionary?["CFBundleDisplayName"] as? String {
return displayName
} else if let name: String = self.infoDictionary?["CFBundleName"] as? String {
return name
}
return "No Name Found"
}
}
以及所有类似的内容
Bundle.main.applicationName
希望这可以帮到您 :)
Swift 4
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String
// 返回应用程序的名称
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
}
如果应用程序包含CFBundleDisplayName
这个键,Finder、系统框架和大多数其他应用程序都将显示它,因此只返回CFBundleName
会导致用户看到不正确的名称。
大多数直接访问信息字典的答案会忽略本地化字符串文件,因此也可能返回错误的名称。在这种情况下,Finder将显示本地化名称。
虽然Info.plist
文件中CFBundleDisplayName
是可选的,但实际上CFBundleName
并不是必须添加的。如果您忘记添加它,仍然不会对系统造成任何影响。但是,大多数用户可能永远不会注意到,此时大多数答案可能根本无法返回有意义的内容。
以下是我的解决方案(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)
}
这种解决方案有什么优点?
它会首先检查CFBundleDisplayName
,仅在未找到时回退到CFBundleName
。
object()
方法总是在本地化版本的info字典上操作,因此如果存在本地化,则会自动使用。
如果字典中既没有CFBundleDisplayName
也没有CFBundleName
,则代码会回退到仅使用磁盘上的包文件名而不带扩展名(因此"My Cool App.app"将成为"My Cool App"),这是一个后备选项,以便此函数永远不会返回nil
。
简单方法:
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 appDisplayName = Bundle.main.infoDictionary?["CFBundleName"] as? String
这是可选项,因此请将其放入if let或guard语句中。
这个在Swift 4.2中对我有效。
guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
return version
} else {
return ""
}