如何在Swift中获取应用程序名称?
谷歌搜索给了我这个:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
我将其转换为Swift;错误-方法不存在:
NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")
Answers:
这应该工作:
NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
infoDictionary
被声明为a,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)
}
CFBundleName
CFBundleDisplayName
是正确的值:“ iPhone主屏幕上的应用程序名称来自CFBundleDisplayName(或“ Bundle显示名称”,即Xcode中的人类可读字符串)”
CFBundleDisplayName
。但是,如果无法使用,则应退回到CFBundleName
。请参阅下面的答案。
我创建了一个简单的扩展名,以获取显示在主屏幕上图标下的应用程序名称。
默认情况下,仅CFBundleName
设置应用程序。但是,某些应用程序设置了CFBundleDisplayName
(捆绑包的用户可见名称)来更改应用程序图标下的标题。通常会添加空格,例如,包名称“ 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
斯威夫特4
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String
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 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中的更多内容
//返回应用名称
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
}
刚返回的所有答案CFBundleName
通常都不会返回用户期望的名称,就像包中有CFBundleDisplayName
,则Finder,系统框架和大多数其他应用程序会显示此键。
大多数答案仅直接访问信息字典,但是信息字典可以通过字符串文件进行本地化,并且在直接访问它们时,也将忽略此本地化,因此可能会返回错误的名称,因为Finder将显示本地化的名称。
虽然CFBundleDisplayName
在Info.plist
文件中是可选的CFBundleName
,但实际上不是可选的,但是如果您忘记添加它,则系统中不会出现任何中断,因此您的信息字典已损坏,但是大多数用户可能永远不会注意到,在这种情况下,大多数答案的代码可能根本不返回任何有意义的东西。
这是我的解决方案(快速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()
方法始终在信息字典的本地化版本上运行,因此,如果存在本地化,将自动使用它。
如果字典中CFBundleDisplayName
也不CFBundleName
存在,则代码将退回到仅使用磁盘文件包中的文件名而没有扩展名(因此“ My Cool App.app”将为“ My Cool App”),这是一个后备版本,因此此功能将永不返回nil
。
对于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)'")
试试这个
let bundleID = NSBundle.mainBundle().bundleIdentifier
com.mycompany.appname
)