Swift 4 JSON decoding when type is only known at runtime(仅在运行时知道类型时的SWIFT 4 JSON解码)
问题描述
当要解码的类型在运行时仅已知时,是否可以使用SWIFT 4中的Decodable
协议对JSON对象进行解码?
我有一个各种各样的注册表,它将String
标识符映射到我们要解码的类型,如下所示:
import Foundation
struct Person: Decodable {
let forename: String
let surname: String
}
struct Company: Decodable {
let officeCount: Int
let people: [Person]
}
let registry: [String:Decodable.Type] = [
"Person": Person.self,
"Company": Company.self
]
let exampleJSON = """
{
"forename": "Bob",
"surname": "Jones"
}
""".data(using: .utf8)!
let t = registry["Person"]!
try! JSONDecoder().decode(t, from: exampleJSON) // doesn't work :-(
我说对了吗?还是有更好的办法?
推荐答案
您的设计确实很独特,但不幸的是,我认为您遇到了SWIFT类型系统的边缘问题。基本上,协议不符合其自身,因此,您的一般Decodable.Type
在这里是不够的(即,您确实需要一个具体的类型来满足类型系统要求)。这可能解释了您出现的错误:
无法使用类型为(Decodable.Type, from: Data)
的参数列表调用decode
。需要(T.Type, from: Data)
类型的参数列表。
但是,话虽如此,确实有一个(脏的!)绕过这件事。首先,创建一个虚拟DecodableWrapper
来保存您的运行时类型Decodable
:
struct DecodableWrapper: Decodable {
static var baseType: Decodable.Type!
var base: Decodable
init(from decoder: Decoder) throws {
self.base = try DecodableWrapper.baseType.init(from: decoder)
}
}
然后这样使用:
DecodableWrapper.baseType = registry["Person"]!
let person = try! JSONDecoder().decode(DecodableWrapper.self, from: exampleJSON).base
print("person: (person)")
打印预期结果:
人:人(名:"Bob",姓:"Jones")
这篇关于仅在运行时知道类型时的SWIFT 4 JSON解码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!