如何在 Swift 中使用键值编码获取全局常量?
How do you fetch a global constant using key-value coding in Swift?
我正在编写一个方法,它将给出 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
时崩溃:
Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[<MyProject.MyViewController 0x7fd83d81c8b0>
valueForUndefinedKey:]: this class is not key value coding-compliant
for the key 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())
}
}
这是因为您可能不得不改用这些变量:
print("\(CNPostalAddress.localizedString(forKey: "subLocality"))")
print("\(CNPostalAddress.localizedString(forKey: "street"))")
所以而不是
let keyPathKey = "CNPostalAddress\(field)Key"
你应该使用
let keyPathKey = "\(field)"
它区分大小写,因此您可能需要进行一些调整。
参见 here
首先 value(forKey: keyPathKey)
是 NSKeyValueCoding
协议中定义的方法,您在 viewController 中调用该方法,这就是为什么要崩溃以避免崩溃的原因,您必须实现该方法在你的 ViewController
override func value(forKey key: String) -> Any? {
}
但无论如何我认为您不需要在第一个实例中调用此方法
func localizedAddressFieldName(for field: String) -> String? {
let localizationKey = "CNPostalAddress\(field)Key"
return CNPostalAddress.localizedString(forKey: localizationKey)
}
如果您的密钥未在 CNPostalAddress
中定义,则结果将为空字符串
我正在编写一个方法,它将给出 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
时崩溃:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyProject.MyViewController 0x7fd83d81c8b0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key 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())
}
}
这是因为您可能不得不改用这些变量:
print("\(CNPostalAddress.localizedString(forKey: "subLocality"))")
print("\(CNPostalAddress.localizedString(forKey: "street"))")
所以而不是
let keyPathKey = "CNPostalAddress\(field)Key"
你应该使用
let keyPathKey = "\(field)"
它区分大小写,因此您可能需要进行一些调整。
参见 here
首先 value(forKey: keyPathKey)
是 NSKeyValueCoding
协议中定义的方法,您在 viewController 中调用该方法,这就是为什么要崩溃以避免崩溃的原因,您必须实现该方法在你的 ViewController
override func value(forKey key: String) -> Any? {
}
但无论如何我认为您不需要在第一个实例中调用此方法
func localizedAddressFieldName(for field: String) -> String? {
let localizationKey = "CNPostalAddress\(field)Key"
return CNPostalAddress.localizedString(forKey: localizationKey)
}
如果您的密钥未在 CNPostalAddress
中定义,则结果将为空字符串