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

时间:2018-01-19 13:56:00

标签: ios swift localization key-value-observing nslocalizedstring

我正在编写一个方法,它将提供CNPostalAddress元素的本地化名称。我试图检索的本地化密钥是全局常量。

/// 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
    }
}

但是,使用以下日志获取localizationKey时应用程序崩溃:

  

因未捕获的异常终止应用' NSUnknownKeyException',   原因:' [< MyProject.MyViewController 0x7fd83d81c8b0>   valueForUndefinedKey:]:此类不符合键值编码   对于密钥CNPostalAddressStreetKey。'

CNPostalAddressStreetKey是有效密钥,如Apple docs所示,但是是全局常量。

解决方案

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())
    }
}

2 个答案:

答案 0 :(得分:0)

这是因为您可能不得不使用这些变量:

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

所以而不是

let keyPathKey = "CNPostalAddress\(field)Key"

你应该使用

let keyPathKey = "\(field)"

它区分大小写,因此您可能需要进行一些调整。

请参阅here

答案 1 :(得分:0)

第一个value(forKey: keyPathKey)NSKeyValueCoding协议中定义的方法,您在viewController中调用该方法,这就是崩溃的原因,以避免您必须在{{1}中实现该方法的崩溃}

ViewController

但无论如何我认为您不需要在第一个实例中调用此方法

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

}

如果您的密钥未在func localizedAddressFieldName(for field: String) -> String? { let localizationKey = "CNPostalAddress\(field)Key" return CNPostalAddress.localizedString(forKey: localizationKey) } 中定义,则结果将为空字符串