Почему не соответствуют протоколу, кодируемому, декодируемому? - PullRequest
2 голосов
/ 13 октября 2019

У меня следующая структура кода. Если я пропущу часть кодирования, код будет запущен. Я реализовал StringConverter для преобразования строки в Int (bySundell Swift Side)

struct Video: Codable {
    var title: String
    var description: String
    var url: URL
    var thumbnailImageURL: URL

    var numberOfLikes: Int {
        get { return likes.value }

    }

    private var likes: StringBacked<Int>
    enum CodingKeys: String, CodingKey{
        case title = "xxx"
        case description = "jjjj"
        case url = "url"
        case thumbnailImageURL = "jjjjjjjj"
        case numberofLikes = "jjjjjkkkk"

    }

}


// here the code for converting the likes
protocol StringRepresentable: CustomStringConvertible {
    init?(_ string: String)
}

extension Int: StringRepresentable {}
struct StringBacked<Value: StringRepresentable>: Codable {
    var value: Value

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let string = try container.decode(String.self)
        let stringToConvert = string.split(separator: "/").last!.description
        guard let value = Value(stringToConvert) else {
            throw DecodingError.dataCorruptedError(
                in: container,
                debugDescription: """
                Failed to convert an instance of \(Value.self) from "\(string)"
                """
            )
        }

        self.value = value
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(value.description)
    }}

Как я уже сказал, если я опускаю часть Codingkeys, она не показывает ошибку. Я просто создал бы структуру, где я получаю строку из Rest API и хочу конвертировать в Int для моей базы данных, используя Codable. Спасибо Арнольд

1 Ответ

1 голос
/ 13 октября 2019

Когда вы определяете CodingKeys, вам нужно предоставить ключ для каждого необязательного / неинициализированного свойства, чтобы компилятор знал, как инициализировать при декодировании. Если применить это к Video, то это будет выглядеть так:

struct Video: Codable {

    var title: String
    var description: String
    var url: URL
    var thumbnailImageURL: URL

    var numberOfLikes: Int {
        return likes.value

    }

    private var likes: StringBacked<Int>

    enum CodingKeys: String, CodingKey{
        case title = "xxx"
        case description = "jjjj"
        case url = "url"
        case thumbnailImageURL = "jjjjjjjj"
        case likes = "jjjjjkkkk"

    }
}

Если вы внимательно посмотрите, это свойство private var likes: StringBacked<Int> не было предоставлено ни в одном CodingKey в перечислении, поэтому компилятор жаловался. Я обновил перечисление с этим регистром case likes = "jjjjjkkkk" и удалил case numberofLikes = "jjjjjkkkk", потому что numberofLikes является вычисляемым свойством только для чтения, которое не требует анализа.

...