-2
{"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"}

I'm getting above json data in string format and i'm parsing with JSONSerialization like below method. I can able to print value data in console but how can i access inside values based on keys.

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

Printing in Console:

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}]

How can I print Status value in this Dictionary? Thanks in advance.

Yoom
  • 27
  • 5
  • 1
    duplicate of https://stackoverflow.com/questions/38831641/swift-could-not-cast-value-of-type-nscfstring-to-nsdictionary. – Wings May 13 '19 at 09:52
  • @wings I'm unable to make change as required based on this answer can you suggest me how to fix it. – Yoom May 13 '19 at 10:07

2 Answers2

2

There are two major issues:

  1. The object for key value is a String (apparently JSON). That's what the error clearly says.
  2. But actually it's not valid JSON because JSON strings must be wrapped in double quotes, single quotes are not supported.

You need two extra steps: Replace the single quotes with double quotes and deserialize the JSON string separately.

And the object is an array. Either use a loop or get an item by index

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)}
vadian
  • 274,689
  • 30
  • 353
  • 361
1

jsonDict["value"] is a json string not a dictionary

let truckStr = jsonDict["value"] as! String
let jsonDic = try! JSONSerialization.jsonObject(with:Data(truckStr.utf8)) as! [String: Any] 
print(jsonDic["Status"])
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • After keeping your code i'm getting this exception How can i fix here--> Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 1." UserInfo={NSDebugDescription=No string key for value in object around character 1.} – Yoom May 13 '19 at 10:04