从 JSONDecoder.decode() 的字符串动态获取 class 类型
Get class type dynamically from string for JSONDecoder.decode()
我想解码 json websocket "notification" 的响应,其中通知类型在 json 响应中。
JSON 示例:
{
"jsonrpc": "2.0",
"method": "Application.OnVolumeChanged",
"params": {
"data": {
"muted": false,
"volume": 88.6131134033203125
},
"sender": "xbmc"
}
}
这是我目前拥有的:
func notificationMessage(text: String) {
do {
if let jsonData = text.data(using: .utf8),
let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let method = json["method"] as? String,
let methodName = method.split(separator: ".").last?.description {
let decoder = JSONDecoder()
let object = try decoder.decode(OnVolumeChanged.self, from: jsonData)
print(object)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
现在我想用 methodName
而不是 OnVolumeChanged.self
。
但我不想在 methodName 上做一个巨大的 switch case,因为我可以获得数百种不同的方法
我试过 NSClassFromString(methodName)
但这给了我 AnyClass?
这不是具体类型。
有没有办法从字符串中获取 class 类型?
I have faced the same problem and here is my solution. You can add
methods to Mapper dictionary any time you want.
//1
let Mapper: [String: Any] = ["OnVolumeChanged" : OnVolumeChanged.self]
//2
func notificationMessage(text: String) {
do {
if let jsonData = text.data(using: .utf8),
let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let method = json["method"] as? String,
let methodName = method.split(separator: ".").last?.description {
let className = Mapper[methodName] as! Codable.Type
let object = try className.init(jsonData: jsonData)
print(object)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
//3
extension Decodable {
init(jsonData: Data) throws {
self = try JSONDecoder().decode(Self.self, from: jsonData)
}
}
我想解码 json websocket "notification" 的响应,其中通知类型在 json 响应中。
JSON 示例:
{
"jsonrpc": "2.0",
"method": "Application.OnVolumeChanged",
"params": {
"data": {
"muted": false,
"volume": 88.6131134033203125
},
"sender": "xbmc"
}
}
这是我目前拥有的:
func notificationMessage(text: String) {
do {
if let jsonData = text.data(using: .utf8),
let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let method = json["method"] as? String,
let methodName = method.split(separator: ".").last?.description {
let decoder = JSONDecoder()
let object = try decoder.decode(OnVolumeChanged.self, from: jsonData)
print(object)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
现在我想用 methodName
而不是 OnVolumeChanged.self
。
但我不想在 methodName 上做一个巨大的 switch case,因为我可以获得数百种不同的方法
我试过 NSClassFromString(methodName)
但这给了我 AnyClass?
这不是具体类型。
有没有办法从字符串中获取 class 类型?
I have faced the same problem and here is my solution. You can add methods to Mapper dictionary any time you want.
//1
let Mapper: [String: Any] = ["OnVolumeChanged" : OnVolumeChanged.self]
//2
func notificationMessage(text: String) {
do {
if let jsonData = text.data(using: .utf8),
let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let method = json["method"] as? String,
let methodName = method.split(separator: ".").last?.description {
let className = Mapper[methodName] as! Codable.Type
let object = try className.init(jsonData: jsonData)
print(object)
}
} catch {
print("Error deserializing JSON: \(error)")
}
}
//3
extension Decodable {
init(jsonData: Data) throws {
self = try JSONDecoder().decode(Self.self, from: jsonData)
}
}