如何在 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:)
是 Apple 鼓励的:
“与其他访问方法相比,使用此方法是首选,因为当键可用时,它会返回键的本地化值。”
extension Bundle {
var displayName: String? {
return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
}
}
访问捆绑包显示名称:
if let displayName = Bundle.main.displayName {
print(displayName)
}
默认情况下,应用程序仅设置
CFBundleName
。但是,某些应用程序设置
CFBundleDisplayName
(捆绑包的用户可见名称) 来更改应用程序图标下的标题。添加空格是经常发生的情况,例如捆绑包名称“ExampleApp”可以将捆绑包显示名称设置为“示例应用程序”。
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
希望这有帮助:)
斯威夫特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
}
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了解更多信息
CFBundleName
的答案通常不会返回用户期望的名称,就好像捆绑包有一个
CFBundleDisplayName
,然后 Finder、系统框架和大多数其他应用程序都会显示此键。
CFBundleDisplayName
在
Info.plist
文件中是可选的,但
CFBundleName
实际上不是,但如果您忘记添加它,系统中不会出现任何问题,因此您的信息字典已损坏,但大多数用户可能会永远不会注意到,在这种情况下,大多数答案的代码可能根本不会返回任何有意义的内容。
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()
方法始终在信息字典的本地化版本上运行,因此如果存在本地化,则会自动使用它。
CFBundleDisplayName
也不存在
CFBundleName
,则代码将回退到仅使用磁盘上的捆绑文件名而不带扩展名(因此“My Cool App.app”将是“My Cool App”),这是一个后备,因此该函数永远不会返回
nil
。
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 ""
}
let bundleID = Bundle.main.bundleIdentifier
let bundleInfoDict: NSDictionary = Bundle.main.infoDictionary! as NSDictionary
let appName = bundleInfoDict["CFBundleName"] as! String
print(bundleID!)
print(appName)
let infoDictionary: NSDictionary = NSBundle.mainBundle().infoDictionary as NSDictionary!
let appName: NSString = infoDictionary.objectForKey("CFBundleName") as NSString
NSLog("Name \(appName)")
可能仍然有更好的方法来做到这一点,但它至少在我非常有限的测试中正确返回应用程序名称......
extension Bundle {
var displayName: String {
let name = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
return name ?? object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
}
}
let bundleInfoDict: NSDictionary = NSBundle.mainBundle().infoDictionary!
let appName = bundleInfoDict["CFBundleName"] as String
let appName = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleDisplayName") as! String
// Bundle+appName.swift
extension Bundle {
var appName: String {
object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
object(forInfoDictionaryKey: "CFBundleName") as? String ??
""
}
}
// Usage (non optional)
let appName = Bundle.main.appName
适用于 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)'")
extension NSApplication {
static var name: String {
Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String ?? ProcessInfo.processInfo.processName
}
}
let appName = Bundle.main.infoDictionary?.first(where: {$0.key == "CFBundleDisplayName"})?.value as? String ?? "default name"