Используя Swift-4.1, Xcode-9.3.1, iOS-11.3.1
Я использую протокол Codable для декодирования JSON-файла.Все работает, за исключением того момента, когда у меня есть интернационализированное доменное имя (в данном случае с немецким Umlaut "ä
") в URL (пример: http://www.rhätische -zeitung.ch ).
Это приводит к ошибке декодера внутри следующего кода:
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-файл поступает извне, я не могу контролировать его содержимое.И, следовательно, замена URL внутри JSON не вариант!(Поэтому я не могу заменить URL-адрес внутри JSON на принятую форму интернационализированной формы как: www.xn--rhtische-zeitung-wnb.ch
) !!
Я знаю, что существуют методы для помещения пользовательского инициализатора в определение Struct (см. Мойиспытания ниже ...) - но так как новичок в Codable, я не знаю, как это сделать для этой текущей проблемы URL-Umlaut.Пользовательский инициализатор, который я разместил ниже, возвращает ноль для рассматриваемого URL.Что мне нужно изменить ??
Или есть другой способ заставить это JSON-декодирование URL работать с Umlaut ??
Вот структура, на этот раз с пользовательским инициализатором:
(по крайней мере, с помощью этого я могу избавиться от сообщения об ошибке выше ... Но URL теперь ноль, кажется, и это тоже не то, что я хочу)
struct Media: Codable {
var publisher: [MediaPublisher]
}
struct MediaPublisher: Codable {
var title: String?
var homepage_url: URL?
// default initializer
init(title: String?, homepage_url: URL?) {
self.title = title
self.homepage_url = homepage_url
}
// custom initializer
init(from decoder: Decoder) throws {
let map = try decoder.container(keyedBy: CodingKeys.self)
self.title = try? map.decode(String.self, forKey: .title)
self.homepage_url = try? map.decode(URL.self, forKey: .homepage_url)
}
private enum CodingKeys: CodingKey {
case title
case homepage_url
}
}