cocoa - lenguaje - Obtener el nombre de la aplicación en Swift
swift versions (12)
¿Cómo obtengo el nombre de la aplicación en Swift?
Google me dio esto:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
Lo convertí en Swift; error - el método no existe:
NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")
Todas las respuestas que acaban de devolver
CFBundleName
a menudo no devolverán el nombre que espera el usuario, como si los paquetes tuvieran unCFBundleDisplayName
, entonces esta clave se muestra en Finder, frameworks del sistema y en la mayoría de las otras aplicaciones.La mayoría de las respuestas solo acceden directamente al diccionario de información, pero los diccionarios de información se pueden localizar mediante archivos de cadena y al acceder directamente a ellos, esta localización también se ignora y, por lo tanto, se puede devolver un nombre incorrecto, ya que Finder mostrará el nombre localizado.
Aunque
CFBundleDisplayName
es opcional en los archivosInfo.plist
,CFBundleName
realidad no lo es, pero si olvida agregarlo, nada se romperá en su sistema, por lo que tendrá una información corrupta, aunque la mayoría de los usuarios probablemente nunca lo notarán y en ese caso el código de la mayoría de las respuestas puede no devolver nada significativo.
Aquí está mi solución (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)
}
¿Cómo es esta solución mejor?
Verificará
CFBundleDisplayName
primero y solo recurrirá aCFBundleName
si no está presente.El método
object()
siempre opera en la versión localizada del diccionario de información, por lo que si existe una localización, se usará automáticamente.Si no
CFBundleDisplayName
niCFBundleDisplayName
niCFBundleName
en el diccionario, el código vuelve simplemente a usar el nombre de archivo del paquete en el disco sin la extensión (por lo que "My Cool App.app" será "My Cool App"), esto es una alternativa para que este la función nunca devolveránil
.
// Devuelve el nombre de la aplicación
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
}
Creé una extensión simple para obtener el nombre de la aplicación que se muestra debajo del ícono en la pantalla de Inicio.
De forma predeterminada, las aplicaciones solo tienen configurado CFBundleName
. Sin embargo, algunas aplicaciones configuran CFBundleDisplayName
(el nombre visible para el usuario del paquete) para cambiar el título debajo del ícono de la aplicación. Agregar espacios es a menudo el caso, por ejemplo, el nombre del paquete "ExampleApp" podría tener el nombre para mostrar conjunto configurado en "Ejemplo de aplicación".
extension Bundle {
// Name of the app - title under the icon.
var displayName: String? {
return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
object(forInfoDictionaryKey: "CFBundleName") as? String
}
}
Uso:
let appName = Bundle.main.displayName
Creo que esta solución es más elegante. Además, el uso de object(forInfoDictionaryKey:)
es fomentado por Apple :
"El uso de este método es preferible a otros métodos de acceso porque devuelve el valor localizado de una clave cuando hay una disponible".
extension Bundle {
var displayName: String? {
return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
}
}
Acceso al nombre para mostrar del paquete:
if let displayName = Bundle.main.displayName {
print(displayName)
}
Este funciona perfecto para mi
let appName = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleDisplayName") as! String
Esto debería funcionar:
NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
infoDictionary
se declara como var infoDictionary: [NSObject : AnyObject]!
entonces tiene que desenvolverlo, acceder a él como un diccionario Swift (en lugar de usar objectForKey
) y, como el resultado es un AnyObject
, AnyObject
.
Actualizar Swift 3 (Xcode 8 beta 2)
Siempre es mejor usar constantes donde sea posible, también:
Bundle.main.infoDictionary![kCFBundleNameKey as String] as! String
Esto debería ser más como lo que estás buscando:
let infoDictionary: NSDictionary = NSBundle.mainBundle().infoDictionary as NSDictionary!
let appName: NSString = infoDictionary.objectForKey("CFBundleName") as NSString
NSLog("Name /(appName)")
Todavía puede haber una mejor manera de hacerlo, pero al menos devuelve el nombre de la aplicación correctamente en mis pruebas muy limitadas ...
Prueba este,
let bundleID = NSBundle.mainBundle().bundleIdentifier
Prueba esto:
extension Bundle {
var displayName: String {
let name = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
return name ?? object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
}
}
manera simple:
let appName = NSBundle.mainBundle().infoDictionary?[kCFBundleNameKey as String] as? String
manera conveniente:
extension NSBundle {
class func mainInfoDictionary(key: CFString) -> String? {
return self.mainBundle().infoDictionary?[key as String] as? String
}
}
print(NSBundle.mainInfoDictionary(kCFBundleNameKey))
kCFBundleNameKey - Clave de Info.plist estándar, ver más en CFBundle
Swift 4
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String
let bundleInfoDict: NSDictionary = NSBundle.mainBundle().infoDictionary!
let appName = bundleInfoDict["CFBundleName"] as String