Получить имя приложения в Swift

Как получить имя приложения в Swift?

Googling дал мне это:

[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];

Я преобразовал его в Swift; error - метод не существует:

NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName")

Ответ 1

Это должно работать:

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

Ответ 2

Я считаю, что это решение более элегантно. Что еще, используя object(forInfoDictionaryKey:) рекомендованный Apple:

"Использование этого метода предпочтительнее других методов доступа, потому что оно возвращает локализованное значение ключа, когда оно доступно".

extension Bundle {
    var displayName: String? {
        return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
    }
}

Доступ к отображаемому имени пучка:

if let displayName = Bundle.main.displayName {
    print(displayName)
}

Ответ 3

Я создал простое расширение, чтобы получить имя приложения, которое отображается под значком на главном экране.

По умолчанию приложения имеют только CFBundleName. Однако некоторые приложения устанавливают CFBundleDisplayName (Видимое пользователем имя пакета), чтобы изменить заголовок под значком приложения. Добавление пространств часто происходит, например. имя пакета "ExampleApp" может иметь отображаемое имя пакета для "Пример приложения".

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

Swift 4

let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String

Ответ 5

Тот же ответ в 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()

Надеюсь, это поможет :)

Ответ 6

простой способ:

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

Ответ 7

Это больше похоже на то, что вы ищете:

let infoDictionary: NSDictionary = NSBundle.mainBundle().infoDictionary as NSDictionary!
let appName: NSString = infoDictionary.objectForKey("CFBundleName") as NSString

NSLog("Name \(appName)")

Там может быть лучший способ сделать это, но он по крайней мере возвращает имя приложения правильно в моем очень ограниченном тестировании...

Ответ 8

  • Все ответы, которые только что возвращают CFBundleName, часто не возвращают имя, которое ожидает пользователь, как если бы пакеты имели CFBundleDisplayName, тогда этот ключ отображается Finder, системные рамки и большинство других приложений.

  • В большинстве ответов только прямой доступ к информационному словарю, но справочные словари могут быть локализованы строковыми файлами и при непосредственном доступе к ним эта локализация также игнорируется, и, следовательно, снова может быть возвращено неправильное имя, так как Finder будет отображать локализованные имя.

  • В то время как CFBundleDisplayName является необязательным в файлах Info.plist, CFBundleName на самом деле нет, но если вы забыли его добавить, в вашей системе ничего не сломается, поэтому у вас есть коррумпированная информация dict, но большинство пользователей, вероятно, никогда не заметят, и в этом случае большинство ответов кода не могут вообще ничего не возвращать.

Здесь мое решение (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() всегда работает с локализованной версией словаря информации, поэтому, если локализация существует, она будет автоматически использоваться.

  • Если в словаре нет CFBundleDisplayName и CFBundleName, код возвращается только к использованию имени файла пакета на диске без расширения (так что "My Cool App.app" будет "My Cool App" "), это резервное копирование, так что эта функция никогда не вернет nil.

Ответ 9

Попробуйте следующее:

extension Bundle {
    var displayName: String {
        let name = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
        return name ?? object(forInfoDictionaryKey: kCFBundleNameKey as String) as! String
    }
}

Ответ 10

//Возвращает имя приложения

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
}

Ответ 11

let appDisplayName = Bundle.main.infoDictionary?["CFBundleName"] as? String

Это необязательно, поэтому вставьте его, если хотите, или охраняйте выражение.

Ответ 12

let bundleInfoDict: NSDictionary = NSBundle.mainBundle().infoDictionary!
let appName = bundleInfoDict["CFBundleName"] as String

Ответ 13

Это работает идеально для меня

let appName = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleDisplayName") as! String

Ответ 14

Это то, что работало для меня в 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)

Ответ 15

Этот работает для меня в Swift 4.2

guard let dictionary = Bundle.main.infoDictionary else { return "" }
if let version: String = dictionary["CFBundleDisplayName"] as? String {
   return version
} else {
   return ""
}

Ответ 16

Попробуйте это,

let bundleID = NSBundle.mainBundle().bundleIdentifier