[英]Using Codable when JSON input represents multiple subclasses of a Codable type
假設我有一些JSON,如下所示:
{
"some-random-key": {
"timestamp": 1234123423
"type": "text",
"content": "Hello!"
},
"some-other-key": {
"timestamp": 21341412314
"type": "image",
"path": "/path/to/image.png"
}
}
此JSON表示兩個消息對象。 這是我想代表他們的方式(快速4):
class Message: Codable {
let timestamp: Int
// ...codable protocol methods...
}
class TextMessage: Message { // first message should map to this class
let content: String
// ...other methods, including overridden codable protocol methods...
}
class ImageMessage: Message { // second message should map to this class
let path: String
// ...other methods, including overridden codable protocol methods...
}
如何使用JSON中的“ type”屬性來告訴Codable初始化哪個子類? 我的第一個直覺是使用枚舉作為中介,這使我可以在字符串表示形式和元類型之間進行選擇
enum MessageType: String {
case image = "image"
case text = "text"
func getType() -> Message.Type {
switch self {
case .text: return TextMessage.self
case .image: return ImageMessage.self
}
}
init(type: Message.Type) {
switch type {
case TextMessage.self: self = .text
case ImageMessage.self: self = .image
default: break
}
}
}
但是,此處的init會導致編譯器錯誤-
Expression pattern of type 'TextMessage.Type' cannot match values of type 'Message.Type'
是否有規范/可接受的方式來處理這種情況? 為什么getType函數執行時,這里的init不能編譯?
我會采用這種方法:
static func createMessage(with json: [String: Any]) -> Message? {
guard let typeString = json["type"] as? String,
let type = MessageType(rawValue: typeString) else { return nil }
switch type {
case .image: return ImageMessage(....
等等
關鍵字“ is”檢查元類型是否表示另一個元類型的子類。 此代碼有效:
init(type: Message.Type) {
switch type {
case is TextMessage.Type: self = .text
case is ImageMessage.Type: self = .text
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.