Умлаут в URL не удается Codable (Swift) - что делать? - PullRequest
0 голосов
/ 18 мая 2018

Используя 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
    }
}
...