Search code examples
iosswiftswift4nsjsonserialization

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

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.


Solution

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