Cocoa 在Swift中获取应用程序名称
如何在Swift中获取应用程序名称 谷歌给了我这个:Cocoa 在Swift中获取应用程序名称,cocoa,swift,Cocoa,Swift,如何在Swift中获取应用程序名称 谷歌给了我这个: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; 我把它改成了斯威夫特;错误-方法不存在: NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName") 试试这个 let bundleID = NSBundle.mainBundle().bundleIdentifier 这应该
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
我把它改成了斯威夫特;错误-方法不存在:
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)")
也许还有更好的方法可以做到这一点,但在我非常有限的测试中,它至少会正确返回应用程序名称…这应该可以:
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 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
我相信这个解决方案更优雅。此外,使用对象(forInfoDictionaryKey:)
是:
“与其他访问方法相比,使用此方法更可取,因为它会在键可用时返回键的本地化值。”
访问包显示名称:
if let displayName = Bundle.main.displayName {
print(displayName)
}
所有只返回CbundleName
的答案通常不会返回用户期望的名称,就好像捆绑包有一个CbundleDisplayName
,那么这个键会由Finder、系统框架和大多数其他应用程序显示
大多数答案只是直接访问信息字典,但信息字典可以通过字符串文件进行本地化,当直接访问它们时,这种本地化也会被忽略,因此可能会再次返回错误的名称,因为Finder将显示本地化的名称
虽然CbundleDisplayName
在Info.plist
文件中是可选的,CbundleName
实际上不是可选的,但如果忘记添加它,系统中不会出现任何故障,因此您的信息目录已损坏,然而,大多数用户可能永远不会注意到,在这种情况下,大多数代码的答案可能不会返回任何有意义的东西
以下是我的解决方案(Swift 3):
这个解决方案如何更好
它将首先检查CFBundleDisplayName
,如果不存在,则返回到CFBundleName
object()
方法始终在信息字典的本地化版本上运行,因此如果存在本地化,将自动使用它
如果字典中既不存在CbundleDisplayName
也不存在CbundleName
,则代码会退回到仅使用磁盘上的捆绑文件名,而不使用扩展名(因此“My Cool App.App”将是“My Cool App”),这是一个回退,因此此函数将永远不会返回nil
试试这个:
extension Bundle {
var displayName: String {
let name = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
return name ?? object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
}
}
我创建了一个简单的扩展来获取主屏幕图标下显示的应用程序名称
默认情况下,应用程序仅设置了CFBundleName
。但是,有些应用程序会设置CFBundleDisplayName
(捆绑包的用户可见名称)以更改应用程序图标下的标题。通常情况下会添加空格,例如捆绑包名称“ExampleApp”可能会将捆绑包显示名称设置为“ExampleApp”
用法:
let appName = Bundle.main.displayName
Swift 4
让appName=Bundle.main.object(forInfoDictionaryKey:“CbundleDisplayName”)作为!字符串
//返回应用程序的名称
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 ""
}
}
}
guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
return version
} else {
return ""
}
你可以像下面那样使用它
let appName = Bundle.appName()
希望这有帮助:)
它是可选的,所以把它放在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)
这一款适合我在《雨燕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 ""
}
}
}
guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
return version
} else {
return ""
}
对于swift 5,iOS 13*
如前所述,它是可选的,所以请将其放在一个guard语句中。我使用struct执行此操作:
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)'")
这将返回bundle标识符,而不是您可以访问NSBundle.mainBundle()的名称(即com.mycompany.appname
).infoDictionary读取项目的plist配置文件cfbundleIdentifier的目的不同。我是唯一一个认为推荐强制转换非常讽刺的人吗?CFBundleName可能并不总是向用户显示的应用程序的名称。请参见下面我的答案,如何获得主屏幕图标下显示的应用程序名称。@VadimBulavin和MariánČerný给出的答案更好,强制转换也不是惯用的,它必须是CFBundleName
@ixany,以下引用证明CFBundleDisplayName
是正确的值:iPhone主屏幕上的应用程序名称来自CbundleDisplayName(或“Bundle display name”,Xcode中的人类可读字符串)“它应该是CbundleDisplayName
。但如果不可用,则应返回到CFBundleName
。请看下面我的答案。这应该是首选答案。它不仅可以处理这两种情况,而且不需要强制包装,这是一种瘟疫,不应该出现在示例代码中。线程1:致命错误:在展开可选值时意外发现nil
guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
return version
} else {
return ""
}
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)'")