Получение строки JSON в функции декодируемого декодирования - PullRequest
2 голосов
/ 30 июня 2019

Во время декодирования ClassA, которое соответствует Decodable, я хотел бы получить значение одного из свойств для пользовательского декодирования.Как мне этого добиться?

class ClassA: Decodable {

    let title: String?
    let data: MyCustomNotDecodableNSObject?

    private enum CodingKeys: String, CodingKey {
        case title
        case data
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        title = try? container.decode(String.self, forKey: .title)

        let dataRawValue = ? // somehow retrieve the raw value that coresponds to the key "data" (JSON string)
        let theData = MyCustomNotDecodableNSObject(rawData: dataRawValue)
        data = theData
    }
}

Пример синтаксического анализа JSON:

{
    "classA" : {
         "title" = "a title"
         "data" : {
             "key1" : "value 1",
             "key2" : "value 2",
             "key3" : "value 3"
          }
} 

Я хочу получить следующее:

"key1" : "value 1",
"key2" : "value 2",
"key3" : "value 3"

Пожалуйста, не предлагайте соответствие MyCustomNotDecodableNSObjectДекодируемый протокол.Этот класс нельзя изменить.

1 Ответ

1 голос
/ 30 июня 2019

Это довольно сложно сделать.Один способ, который я нашел, - это сначала декодировать нужную часть как [String: Any], используя метод, описанный в этом посте .Затем преобразуйте этот словарь в Data, используя JSONSerialization, что является довольно скучным способом ведения дел, но я не смог найти лучшего способа.

if let dict = try container.decodeIfPresent([String: Any].self, forKey: .data) {
    let dataRawValue = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) // prettyPrinted is optional here
    data = MyCustomNotDecodableNSObject(rawData: dataRawValue)
} else {
    data = nil
}

Если вы действительно хотитеString чтобы перейти на MyCustomNotDecodableNSObject.init, просто позвоните String.init(data:encoding:).

Требуется расширение из связанного поста!

...