Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 在Swift中获取应用程序名称_Cocoa_Swift - Fatal编程技术网

Cocoa 在Swift中获取应用程序名称

Cocoa 在Swift中获取应用程序名称,cocoa,swift,Cocoa,Swift,如何在Swift中获取应用程序名称 谷歌给了我这个: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; 我把它改成了斯威夫特;错误-方法不存在: NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName") 试试这个 let bundleID = NSBundle.mainBundle().bundleIdentifier 这应该

如何在Swift中获取应用程序名称

谷歌给了我这个:

[[[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)'")