简体   繁体   English

类型不符合“可编码”协议

[英]Type does not conform to protocol 'Encodable'

I have a class named Event that I want to make it Codable:我有一个名为 Event 的类,我想让它成为可编码的:

class Event: Codable {
    let name: String
    let action: String
    let data: [String: Any]?

    enum CodingKeys: String, CodingKey {
        case name
        case action
        case data
    }

    init(name: String, action: String, data: [String: Any]?) {
        self.name = name
        self.action = action
        self.data = data
    }

    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try values.decode(String.self, forKey: .name)
        self.action = try values.decode(String.self, forKey: .action)
        let eventDataAsJSONString = try values.decode(String.self, forKey: .data)
        if let eventDataAsData = eventDataAsJSONString.data(using: .utf8) {
            self.data = try? JSONSerialization.jsonObject(with: eventDataAsData, options: []) as? [String: Any]
        } else {
            self.data = nil
        }
    }

    func encode(from encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.name, forKey: .name)
        try container.encode(self.action, forKey: .action)
        if let data = self.data {
            let eventDataAsData = try! JSONSerialization.data(withJSONObject: data, options: [])
            let eventDataAsJSONString = String(data: eventDataAsData, encoding: .utf8)
            try container.encode(eventDataAsJSONString, forKey: .data)
        } else {
            try container.encodeNil(forKey: .data)
        }
    }
}

but I'm getting this error:但我收到此错误:

Type 'Event' does not conform to protocol 'Encodable'

I implemented both init(from decoder: Decoder) and encode(from encoder: Encoder) .我实现了init(from decoder: Decoder)encode(from encoder: Encoder) so what I'm doing wrong here?所以我在这里做错了什么?

I need data property with [String:Any] type, because my users need to store some json-like information with it.我需要[String:Any]类型的data属性,因为我的用户需要用它存储一些类似 json 的信息。

This is how you can use ANY in Codable这就是你如何在 Codable 中使用 ANY

class Event<T: Codable>: Codable {
    let name: String
    let action: String
    let data: [String: T]?

    enum CodingKeys: String, CodingKey {
        case name
        case action
        case data
    }

    init(name: String, action: String, data: [String: T]?) {
        self.name = name
        self.action = action
        self.data = data
    }

    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try values.decode(String.self, forKey: .name)
        self.action = try values.decode(String.self, forKey: .action)
        let eventDataAsJSONString = try values.decode(String.self, forKey: .data)
        if let eventDataAsData = eventDataAsJSONString.data(using: .utf8) {
            self.data = try? JSONSerialization.jsonObject(with: eventDataAsData, options: []) as? [String: T]
        } else {
            self.data = nil
        }
    }

    func encode(from encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.name, forKey: .name)
        try container.encode(self.action, forKey: .action)
        if let data = self.data {
            let eventDataAsData = try! JSONSerialization.data(withJSONObject: data, options: [])
            let eventDataAsJSONString = String(data: eventDataAsData, encoding: .utf8)
            try container.encode(eventDataAsJSONString, forKey: .data)
        } else {
            try container.encodeNil(forKey: .data)
        }
    }
}


     let event = Event<String>(name: "name", action: "action", data: ["String" : "String"]) // Replace <String> with the type u want and pass that in data

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM