Get App Name in Swift

CocoaSwift

Cocoa Problem Overview


How do I get the application name in Swift?

Googling gave me this:

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

I converted it to Swift; error - method doesn't exist:

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

Cocoa Solutions


Solution 1 - Cocoa

This should work:

NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String

infoDictionary is declared as a var infoDictionary: [NSObject : AnyObject]! so you have to unwrap it, access it as a Swift dictionary (rather than use objectForKey), and, as the result is an AnyObject, cast it.

Update Swift 3 (Xcode 8 beta 2)

Always better to use constants (and optionals) where possible, too:

Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String

Solution 2 - Cocoa

I believe this solution is more elegant. What's more, using object(forInfoDictionaryKey:) is encouraged by Apple: > "Use of this method is preferred over other access methods because it returns the localized value of a key when one is available."

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

Accessing bundle display name:

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

Solution 3 - Cocoa

I have created a simple extension to get the app name that is shown under the icon on the Home screen.

By default, apps only have CFBundleName set. Some apps, however, set CFBundleDisplayName (The user-visible name of the bundle) to change the title under the app icon. Adding spaces is often the case, e.g. bundle name "ExampleApp" could have bundle display name set to "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
    }
}

Usage:

let appName = Bundle.main.displayName

Solution 4 - Cocoa

Same answer in 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 ""
        }
    }
}

you can use it like below

let appName = Bundle.appName()

Hope this helps :)

Solution 5 - Cocoa

Swift 4

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

Solution 6 - Cocoa

simple way:

let appName = NSBundle.mainBundle().infoDictionary?[kCFBundleNameKey as String] as? String

convenient way:

extension NSBundle {
    class func mainInfoDictionary(key: CFString) -> String? {
        return self.mainBundle().infoDictionary?[key as String] as? String
    }
}
print(NSBundle.mainInfoDictionary(kCFBundleNameKey))

kCFBundleNameKey – Standard Info.plist key, see more in CFBundle

Solution 7 - Cocoa

// Returns app's name

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
}

Solution 8 - Cocoa

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

It's optional, so put it in if let or guard statement.

Solution 9 - Cocoa

  1. All answers that just return CFBundleName will often not return the name the user expects, as if bundles have a CFBundleDisplayName, then this key is displayed by Finder, system frameworks, and most other apps.

  2. Most answers just directly access the info dictionary but info dictionaries can be localized by string files and when accessing them directly, this localization is also ignored and thus again a wrong name may be returned, as Finder will display the localized name.

  3. While CFBundleDisplayName is optional in Info.plist files, CFBundleName actually isn't, but if you forget to add it, nothing will break in your system, so you have a corrupt info dict, yet most users will probably never notice and in that case the code most answers may not return anything meaningful at all.

Here's my solution (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)
}

How is this solution better?

  1. It will check CFBundleDisplayName first and only fall back to CFBundleName if not present.

  2. The object() method always operates on the localized version of the info dictionary, so if a localization exists, it will automatically be used.

  3. If neither CFBundleDisplayName nor CFBundleName exist in the dictionary, the code falls back to just using the bundle filename on disk without the extension (so "My Cool App.app" will be "My Cool App"), this is a fallback so that this function will never return nil.

Solution 10 - Cocoa

This is what worked for me in Xcode 11.0 and 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)

Solution 11 - Cocoa

This one works for me in Swift 4.2

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

Solution 12 - Cocoa

This should be more like what you are looking for:

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

There may still be a better way to do this but it at least returns the app name correctly in my very limited testing...

Solution 13 - Cocoa

Try this:

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

Solution 14 - Cocoa

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

Solution 15 - Cocoa

This one works perfect for me

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

Solution 16 - Cocoa

For swift 5, iOS 13*

As mentioned before, it‘s an optional, so put it in a guard statement. I do this using a 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

Usage:

print("Model.ProgVariablen.appBundleName: '\(Model.ProgVariablen.appBundleName)'")

Solution 17 - Cocoa

Try this one,

let bundleID = NSBundle.mainBundle().bundleIdentifier

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKaattView Question on Stackoverflow
Solution 1 - CocoaGrimxnView Answer on Stackoverflow
Solution 2 - CocoaVadim BulavinView Answer on Stackoverflow
Solution 3 - CocoaMarián ČernýView Answer on Stackoverflow
Solution 4 - CocoaAbdul RehmanView Answer on Stackoverflow
Solution 5 - CocoaShan YeView Answer on Stackoverflow
Solution 6 - CocoaolsenView Answer on Stackoverflow
Solution 7 - CocoaPratyush PratikView Answer on Stackoverflow
Solution 8 - CocoaPepii15View Answer on Stackoverflow
Solution 9 - CocoaMeckiView Answer on Stackoverflow
Solution 10 - CocoakiddsloppView Answer on Stackoverflow
Solution 11 - CocoaJust AwesomeView Answer on Stackoverflow
Solution 12 - CocoaDan FairaizlView Answer on Stackoverflow
Solution 13 - CocoaA. PoltoratskyiView Answer on Stackoverflow
Solution 14 - CocoazaphView Answer on Stackoverflow
Solution 15 - CocoaalitosunerView Answer on Stackoverflow
Solution 16 - CocoaRvdHView Answer on Stackoverflow
Solution 17 - CocoaChristianView Answer on Stackoverflow