我们说我有一些JSON,就像这样:
{
"some-random-key": {
"timestamp": 1234123423
"type": "text",
"content": "Hello!"
},
"some-other-key": {
"timestamp": 21341412314
"type": "image",
"path": "/path/to/image.png"
}
}
此JSON代表两个消息对象。以下是我想要代表他们的方式(Swift 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中的属性告诉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不在这里编译?
答案 0 :(得分:0)
我会选择这种方法:
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(....
等等
答案 1 :(得分:0)
“is”关键字检查元类型是否表示另一个元类型的子类。此代码有效:
init(type: Message.Type) {
switch type {
case is TextMessage.Type: self = .text
case is ImageMessage.Type: self = .text
}
}