为什么我的结构不符合 Encodable 和 Decodable?

Why my structs doesn't conform to Encodable and Decodable?

提问人:incelemeTRe 提问时间:10/26/2023 最后编辑:HangarRashincelemeTRe 更新时间:10/26/2023 访问量:64

问:

这是我用于解码 JSON 文件的结构。Xcode 给出错误并说它们不符合 和 .这个:EncodableDecodable

struct SocialModel: Codable {
    let id: Int
    let likeCount: Int
    let commentCounts: CommentCounts
    
    enum CodingKeys: String, CodingKey {
        case id
        case likeCount
        case commentCounts
    }
    
    init(id: Int, likeCount: Int, commentCounts: CommentCounts) {
        self.id = id
        self.likeCount = likeCount
        self.commentCounts = commentCounts
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeIfPresent(Int.self, forKey: .id) ?? 123
        likeCount = try container.decode(Int.self, forKey: .likeCount)
        commentCounts = try container.decode(CommentCounts.self, forKey: .commentCounts)
    }
}

struct CommentCounts: Codable {
    let averageRating, anonymousCommentsCount, memberCommentsCount: Int
}

还有这个:

struct ProductModel: Codable {
    let productId: Int
    let name, desc: String
    let productImage: String
    let productPrice: Price
}

struct Price: Codable {
    let value: Int
    let currency: String
}

谁能告诉我为什么?我尝试了很多次构建它们,但最终没有奏效。

json swift struct 解码 可编码

评论

1赞 Sweeper 10/26/2023
无法重现。您的代码将编译。

答:

1赞 Samir Rana 10/26/2023 #1

你的结构不符合 Encodable 和 Decodable 协议,因为你已经实现了自定义初始值设定项,这可能与 Swift 为 Codable 一致性提供的默认编码机制冲突。若要使结构符合 Codable,应实现 init(from:) 和 encode(to:) 方法来指定自定义类型的编码和解码方式。

下面是结构的更新版本,其中包含必要的 init(from:) 和 encode(to:) 方法:

struct SocialModel: Codable {
    let id: Int
    let likeCount: Int
    let commentCounts: CommentCounts

    enum CodingKeys: String, CodingKey {
        case id
        case likeCount
        case commentCounts
    }

    init(id: Int, likeCount: Int, commentCounts: CommentCounts) {
        self.id = id
        self.likeCount = likeCount
        self.commentCounts = commentCounts
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(Int.self, forKey: .id)
        likeCount = try container.decode(Int.self, forKey: .likeCount)
        commentCounts = try container.decode(CommentCounts.self, forKey: .commentCounts)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(likeCount, forKey: .likeCount)
        try container.encode(commentCounts, forKey: .commentCounts)
    }
}

struct CommentCounts: Codable {
    let averageRating, anonymousCommentsCount, memberCommentsCount: Int
}

struct ProductModel: Codable {
    let productId: Int
    let name, desc: String
    let productImage: String
    let productPrice: Price
}

struct Price: Codable {
    let value: Int
    let currency: String
}

通过在 SocialModel 结构中实现 encode(to:) 方法,可以提供有关如何对自定义类型进行编码的说明,从而使结构符合 Encodable 协议。同样,SocialModel 结构中的 init(from:) 方法指定如何解码自定义类型,使结构符合 Decodable 协议。

评论

0赞 incelemeTRe 10/26/2023
谢谢!我将尝试您的代码并在此处回复。