2

我有以下代码结构。如果我省略了 codingkey 部分,代码正在运行。我实现了 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 获取一个字符串,然后我想使用 Codable 为我的数据库转换一个 Int。谢谢阿诺德

4

1 回答 1

1

定义时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它是一个不需要任何解析的只读计算属性。

于 2019-10-13T09:20:32.513 回答