从JSONDecoder.decode()的字符串动态获取类类型

时间:2017-08-13 13:33:47

标签: swift swift4

我想解码websocket"通知"的json响应。通知类型在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?这不是具体的类型。

有没有办法从字符串中获取类类型?

1 个答案:

答案 0 :(得分:1)

  

我遇到了同样的问题,这是我的解决方案。你可以加   您可以随时使用Mapper词典的方法。

// 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)
                    }
                }