Search code examples
swiftjsondecoder

Parsing only few of the fields in json


I am trying to parse following json:

"{\"action\":\"question-answered\",\"data\":{\"type\":\"agreement\",\"questionType\":{},\"answer\":{}}}"

with following model:

    struct SymptomCheckerResult: Codable {
    let action: String?
    
    enum CodingKeys: String, CodingKey {
        case action = "action"
    }
}

I just require value from one key. But my parsing is failing with following error message:

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))

Following is my parsing code:

let jsonData = Data(messageBody.utf8)
    do {
        let symptomCheckerResult = try JSONDecoder().decode(SymptomCheckerResult.self, from: jsonData)
        print(symptomCheckerResult)
    } catch (let error) {
        print(error)
    }

I could have a very long json but I just need values from 1 key but my parsing is always failing. It looks very simple but somehow it is not working for me. Can someone please help me point my mistake?


Solution

  • You have JSON Stringified: Your JSON is a JSON String, it starts with a double quotes. It's not direct JSON.

    If we needed to declare your answer in Swift, it could be:

    let messageBody = """
    "{\\\"action\\\":\\\"question-answered\\\",\\\"data\\\":{\\\"type\\\":\\\"agreement\\\",\\\"questionType\\\":{},\\\"answer\\\":{}}}"
    """
    

    There are actually backslash, it's not the Console that print them because of debugging tools.

    So you need to serialize it first:

    let jsonStr = try JSONDecoder().decoder(String.self, from: jsonData)
    let symptomCheckerResult = try JSONDecoder().decode(SymptomCheckerResult.self, from: Data(jsonStr.utf8)