JSON 正在解析 ---> 无法将“__NSCFString”类型的值 (0x1e5c38f90) 转换为 'NSDictionary' (0x1e5c39bc0)
JSON Parsing---> Could not cast value of type '__NSCFString' (0x1e5c38f90) to 'NSDictionary' (0x1e5c39bc0)
{"msgType":"UPDATE_S","macAddress":"2F-01-01-01-01-01","deviceName":"vMining","deviceType":"vSensor","groupId":"vMiningYo","param”:”truckDetail","value":"[{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]","valueDimension":"JSON","topic":"in/vMiningYo_ios/vMINING","_MessageGateway_TimeMilliseconds":1557471205646,"_MessageGateway_TimeSeconds":1557471205,"_MessageGateway_TimeISO8601":"2019-05-10T06:53:25.646Z","_MessageGateway_MessageClientType":"WS","_MessageGateway_Topic":"in/vMiningYo_ios/vMINING"}
我正在以字符串格式获取以上 json 数据,并且我正在使用 JSONSerialization
进行解析,如下面的方法。我可以在控制台中打印值数据,但如何根据键访问内部值。
func recieveMessage(json:String){
guard let data = json.data(using: .utf16),
let jsonData = try? JSONSerialization.jsonObject(with: data),
let jsonDict = jsonData as? [String: Any],
let param = jsonDict["param"] as? String else {
return
}
if param == "truckDetail"{
print("VALUE:: \(jsonDict["value"]!)")
let truckData = jsonDict["value"]! as! [String:Any]
print(truckData)
print(truckData["Status"])
// if let truckData = jsonDict["value"] as? [String: Any]{
// print(truckData)
// }
}
}
正在控制台中打印:
VALUE:: [{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]
如何打印此词典中的状态值?提前致谢。
jsonDict["value"]
是 json 字符串而不是字典
let truckStr = jsonDict["value"] as! String
let jsonDic = try! JSONSerialization.jsonObject(with:Data(truckStr.utf8)) as! [String: Any]
print(jsonDic["Status"])
有两个个主要问题:
- 键
value
的对象是 String
(显然是 JSON)。错误就是这么说的。
- 但实际上它是无效的JSON因为JSON字符串必须用双引号括起来,不支持单引号。
您需要两个额外的步骤:将单引号替换为双引号并单独反序列化 JSON 字符串。
对象是一个数组。使用循环或通过索引
获取项目
let json = """
{"msgType":"UPDATE_S","macAddress":"2F-01-01-01-01-01","deviceName":"vMining","deviceType":"vSensor","groupId":"vMiningYo","param":"truckDetail","value":"[{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]","valueDimension":"JSON","topic":"in/vMiningYo_ios/vMINING","_MessageGateway_TimeMilliseconds":1557471205646,"_MessageGateway_TimeSeconds":1557471205,"_MessageGateway_TimeISO8601":"2019-05-10T06:53:25.646Z","_MessageGateway_MessageClientType":"WS","_MessageGateway_Topic":"in/vMiningYo_ios/vMINING"}
"""
let data = Data(json.utf8)
do {
if let result = try JSONSerialization.jsonObject(with: data) as? [String:Any],
let param = result["param"] as? String {
if param == "truckDetail" {
let value = result["value"] as! String
let valueString = value.replacingOccurrences(of: "\'", with: "\"")
let valueData = Data(valueString.utf8)
if let valueResult = try JSONSerialization.jsonObject(with: valueData) as? [[String:Any]] {
for item in valueResult {
print(item["Status"] as? String ?? "n/a")
}
}
}
}
} catch { print(error)}
{"msgType":"UPDATE_S","macAddress":"2F-01-01-01-01-01","deviceName":"vMining","deviceType":"vSensor","groupId":"vMiningYo","param”:”truckDetail","value":"[{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]","valueDimension":"JSON","topic":"in/vMiningYo_ios/vMINING","_MessageGateway_TimeMilliseconds":1557471205646,"_MessageGateway_TimeSeconds":1557471205,"_MessageGateway_TimeISO8601":"2019-05-10T06:53:25.646Z","_MessageGateway_MessageClientType":"WS","_MessageGateway_Topic":"in/vMiningYo_ios/vMINING"}
我正在以字符串格式获取以上 json 数据,并且我正在使用 JSONSerialization
进行解析,如下面的方法。我可以在控制台中打印值数据,但如何根据键访问内部值。
func recieveMessage(json:String){
guard let data = json.data(using: .utf16),
let jsonData = try? JSONSerialization.jsonObject(with: data),
let jsonDict = jsonData as? [String: Any],
let param = jsonDict["param"] as? String else {
return
}
if param == "truckDetail"{
print("VALUE:: \(jsonDict["value"]!)")
let truckData = jsonDict["value"]! as! [String:Any]
print(truckData)
print(truckData["Status"])
// if let truckData = jsonDict["value"] as? [String: Any]{
// print(truckData)
// }
}
}
正在控制台中打印:
VALUE:: [{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]
如何打印此词典中的状态值?提前致谢。
jsonDict["value"]
是 json 字符串而不是字典
let truckStr = jsonDict["value"] as! String
let jsonDic = try! JSONSerialization.jsonObject(with:Data(truckStr.utf8)) as! [String: Any]
print(jsonDic["Status"])
有两个个主要问题:
- 键
value
的对象是String
(显然是 JSON)。错误就是这么说的。 - 但实际上它是无效的JSON因为JSON字符串必须用双引号括起来,不支持单引号。
您需要两个额外的步骤:将单引号替换为双引号并单独反序列化 JSON 字符串。
对象是一个数组。使用循环或通过索引
获取项目let json = """
{"msgType":"UPDATE_S","macAddress":"2F-01-01-01-01-01","deviceName":"vMining","deviceType":"vSensor","groupId":"vMiningYo","param":"truckDetail","value":"[{'TruckNo':1,'Status':'Moving to crusher','Speed':0,'CheckPointNumber':16,'CurrentLoad':346,'TirePressureIssueWheelNumber':0,'TirePressure':6,'Longitude':36.835072,'Latitude':-109.059769,'Altitude':1.0}]","valueDimension":"JSON","topic":"in/vMiningYo_ios/vMINING","_MessageGateway_TimeMilliseconds":1557471205646,"_MessageGateway_TimeSeconds":1557471205,"_MessageGateway_TimeISO8601":"2019-05-10T06:53:25.646Z","_MessageGateway_MessageClientType":"WS","_MessageGateway_Topic":"in/vMiningYo_ios/vMINING"}
"""
let data = Data(json.utf8)
do {
if let result = try JSONSerialization.jsonObject(with: data) as? [String:Any],
let param = result["param"] as? String {
if param == "truckDetail" {
let value = result["value"] as! String
let valueString = value.replacingOccurrences(of: "\'", with: "\"")
let valueData = Data(valueString.utf8)
if let valueResult = try JSONSerialization.jsonObject(with: valueData) as? [[String:Any]] {
for item in valueResult {
print(item["Status"] as? String ?? "n/a")
}
}
}
}
} catch { print(error)}