Json URL中的Umlaut无法编码(Swift)-怎么办?
使用Swift-4.1、Xcode-9.3.1、iOS-11.3.1 我使用可编码协议来解码JSON文件。除了在URL中有一个国际化域名(在本例中,带有一个德语Umlaut“Json URL中的Umlaut无法编码(Swift)-怎么办?,json,swift,url,decode,codable,Json,Swift,Url,Decode,Codable,使用Swift-4.1、Xcode-9.3.1、iOS-11.3.1 我使用可编码协议来解码JSON文件。除了在URL中有一个国际化域名(在本例中,带有一个德语Umlaut“ä”)的那一刻(例如:),一切都正常 这会导致以下代码中出现解码器错误: func loadJSON(url: URL) -> Media? { do { let data = try Data(contentsOf: url) let decoder = JSONDecoder
ä
”)的那一刻(例如:),一切都正常
这会导致以下代码中出现解码器错误:
func loadJSON(url: URL) -> Media? {
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let media = try decoder.decode(Media.self, from: data)
return media
} catch {
print("error:\(error)")
}
return nil
}
错误消息是:
The Codable protocol does not seem to be able to decode this URL form
my JSON-file into the needed Struct.
以下是结构:
struct Media: Codable {
var publisher: [MediaPublisher]
}
struct MediaPublisher: Codable {
var title: String?
var homepage_url: URL?
}
以下是JSON摘录:
{
"publisher": [
{
"title" : "Rhätische-Zeitung",
"homepage_url" : "http://www.rhätische-zeitung.ch",
}
]
}
由于JSON文件来自外部,因此我无法控制内容。因此,替换JSON中的URL不是一个选项!
(因此,我无法将JSON中的URL替换为公认的国际化形式,例如:www.xn--rhtische zeitung wnb.ch
)
我知道有一些技术可以将自定义初始值设定器放入结构定义中(请参见下面的试用…)-但是由于对Codable来说是新的,我不知道如何解决当前的URL Umlaut问题。我在下面放置的自定义初始化器对于问题的URL返回nil。我需要改变什么
或者有没有另一种方法可以使用Umlaut对URL进行JSON解码
这是结构,这次使用的是自定义初始化器:
(至少这样,我可以摆脱上面的错误消息…但URL现在似乎为零,这也不是我想要的)
我只是被同样的问题绊倒了。这个解决方案实际上相当简单,在我的简短测试中效果很好 这样做的目的是不让解码器将值解码为URL,因为它希望后面的字符串采用某种格式。我们可以做的是直接将值解码为字符串,并手动将其转换为URL 我写了一个小小的扩展来完成这项工作:
extension KeyedDecodingContainer {
/// Decodes the string at the given key as a URL. This allows for special characters like umlauts to be decoded correctly.
func decodeSanitizedURL(forKey key: KeyedDecodingContainer<K>.Key) throws -> URL {
let urlString = try self.decode(String.self, forKey: key)
// Sanitize string and attempt to convert it into a valid url
if let urlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: urlString) {
return url
}
// Throw an error as the URL could not be decoded
else {
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Could not decode \(urlString)")
}
}
}
希望这能有所帮助,即使问题有点老了
extension KeyedDecodingContainer {
/// Decodes the string at the given key as a URL. This allows for special characters like umlauts to be decoded correctly.
func decodeSanitizedURL(forKey key: KeyedDecodingContainer<K>.Key) throws -> URL {
let urlString = try self.decode(String.self, forKey: key)
// Sanitize string and attempt to convert it into a valid url
if let urlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: urlString) {
return url
}
// Throw an error as the URL could not be decoded
else {
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Could not decode \(urlString)")
}
}
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.url = try values.decodeSanitizedURL(forKey: .url)
}