简体   繁体   English

如何在Swift中使用键值编码获取全局常量?

[英]How do you fetch a global constant using key-value coding in Swift?

I am writing a method that will give localized names of CNPostalAddress elements. 我正在写一个方法,该方法将给出CNPostalAddress元素的本地化名称。 The localization keys I am attempting to retrieve are global constants. 我尝试检索的本地化关键字是全局常量。

/// Get the localised name of a CNPostalAddress element
///
/// - Parameter field: CNPostalAddress element name (Street, SubLocality, City, SubAdministrativeArea, State, PostalCode, Country, ISOCountryCode)
/// - Returns: localized name of the address field


func localizedAddressFieldName(for field: String) -> String? {
    let keyPathKey = "CNPostalAddress\(field)Key"

    if let localizationKey = value(forKey: keyPathKey) as? String {
        return CNPostalAddress.localizedString(forKey: localizationKey)
    } else {
        return nil
    }
}

However, the application crashes when getting the the localizationKey with the following log: 但是,使用以下日志获取localizationKey时,应用程序崩溃:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyProject.MyViewController 0x7fd83d81c8b0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key CNPostalAddressStreetKey.' 由于未捕获的异常“ NSUnknownKeyException”而终止应用程序,原因:“ [<MyProject.MyViewController 0x7fd83d81c8b0> valueForUndefinedKey:]:此类不适用于密钥CNPostalAddressStreetKey的密钥值编码兼容。”

CNPostalAddressStreetKey is a valid key, as shown in Apple docs , but is a Global constant. Apple docs所示, CNPostalAddressStreetKey是有效的密钥,但是全局常量。

Solution

extension CNPostalAddress {
    class func localizedAddressFieldName(for field: String) -> String? {
        let localizationKey = field.decapitalizingFirstLetter()
        return CNPostalAddress.localizedString(forKey: localizationKey)
    }
}

extension String {
    func decapitalizingFirstLetter() -> String {
        let firstLetterLowercase = String(prefix(1)).lowercased()
        return firstLetterLowercase + String(dropFirst())
    }
}

it's because you may have to use those variables instead: 这是因为您可能不得不使用这些变量:

print("\(CNPostalAddress.localizedString(forKey: "subLocality"))")
print("\(CNPostalAddress.localizedString(forKey: "street"))")

so instead of 所以代替

let keyPathKey = "CNPostalAddress\(field)Key"

you should use 你应该使用

let keyPathKey = "\(field)"

it's case sensitive, so you might have to make some adjustments. 区分大小写,因此您可能需要进行一些调整。

see here 这里

First value(forKey: keyPathKey) is a method defined in NSKeyValueCoding protocol, you are calling that method in your viewController that is why is crashing to avoid the crash you have to implement that method in your ViewController 第一个value(forKey: keyPathKey)是在NSKeyValueCoding协议中定义的方法,您在viewController中调用该方法,这就是为什么崩溃以避免在您必须在ViewController实现该方法而崩溃的原因

override func value(forKey key: String) -> Any? {

}

but anyway I think you don't need call this method in first instance 但无论如何,我认为您不必在一开始就调用此方法

func localizedAddressFieldName(for field: String) -> String? {
    let localizationKey = "CNPostalAddress\(field)Key"

    return CNPostalAddress.localizedString(forKey: localizationKey)
}

If your key is not defined in CNPostalAddress the result will be an empty string 如果您的密钥未在CNPostalAddress定义,则结果将为空字符串

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM