Swift Codable не может настроить только нужные ключи - PullRequest
0 голосов
/ 22 октября 2018

Мне нужно вручную настроить только один ключ кодирования для следующего класса

@objcMembers class Article :Object, Decodable{
        dynamic var id: Int = 0
        dynamic var title: String = ""
        dynamic var image: String = ""
        dynamic var author : String = ""
        dynamic var datePublished: Date?
        dynamic var body: String?
        dynamic var publisher: String?
        dynamic var url: String?

    }

, поэтому мне нужно добавить следующее перечисление

private enum CodingKeys: String, CodingKey {
        case id
        case title = "name"
        case image
        case author
        case datePublished
        case body
        case publisher
        case url
    }

Итак, я добавил всех членов классав перечисление CodingKeys для переопределения заголовка на «имя».

Есть ли способ, позволяющий мне добавлять в перечисление только те случаи, которые я хочу настроить ???

1 Ответ

0 голосов
/ 22 октября 2018

Для Xcode 9.3 или новее

Этого можно добиться, комбинируя 3 вещи:

  • A GenericCodingKeys struct, которая позволяет нам создать ключ кодирования с произвольным строковым значением.
  • Функция, которая сопоставляет ключ JSON с именем вашего свойства (nametitle)
  • Установка keyDecodingStrategy = .custom(...) для объекта JSONDecoder

Попробуйте это:

import Foundation

// A struct that allows us to construct arbitrary coding keys
// You can think of it like a wrapper around a string value
struct GenericCodingKeys: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) { self.stringValue = stringValue }
    init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
}

@objcMembers class Article: NSObject, Decodable {
    dynamic var id: Int = 0
    dynamic var title: String = ""
    dynamic var image: String = ""
    dynamic var author : String = ""
    dynamic var datePublished: Date?
    dynamic var body: String?
    dynamic var publisher: String?
    dynamic var url: String?

    static func codingKeyMapper(path: [CodingKey]) -> CodingKey {
        // `name` is the key in JSON. `title` is your property name
        // Here, we map `name` --> `title`
        if path.count == 1 && path[0].stringValue == "name" {
            return GenericCodingKeys(stringValue: "title")!
        } else {
            return path.last!
        }
    }
}

let json = """
{
    "id": 1,
    "name": "A title",
    "image": "An image",
    "author": "Any author",
}
""".data(using: .utf8)!

// Configure the decoder object to use a custom key decoding strategy
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .custom(Article.codingKeyMapper)
let article = try decoder.decode(Article.self, from: json)

print(article.title)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...