Home > Software engineering >  Parse JSON string inside another JSON
Parse JSON string inside another JSON

Time:05-11

I have some JSON that contains another JSON object inside in a form of a string (note quotes around the "jsonString" value):

{
  "jsonString":"{\"someKey\": \"Some value\"}"
}

I know that if "jsonString" didn't have quotes around its value, I would do something like this:

import Foundation

struct Something: Decodable {
  struct SomethingElse: Decodable {
    let someKey: String
  }
  let jsonString: SomethingElse
}

let jsonData = """
               {
                 "jsonString":"{\"someKey\": \"Some value\"}"
               }
               """.data(using: .utf8)!
let something = try! JSONDecoder().decode(Something.self, from: jsonData)

But it doesn't work for my case. It doesn't work even if I treat "jsonString" as a String and do something like this:

init(from decoder: Decoder) throws {
  let container = try decoder.container(keyedBy: SomethingKey.self)

  let jsonStringString = try container.decode(String.self, forKey: .jsonString)
  if let jsonStringData = jsonStringString.data(using: .utf8) {
    self.jsonString = try JSONDecoder().decode(SomethingElse.self, from: jsonStringData)
  } else {
    self.jsonString = SomethingElse(someKey: "")
  }
}
private enum SomethingKey: String, CodingKey {
  case jsonString
}

The error I'm experiencing is:

Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Badly formed object around line 2, column 18." UserInfo={NSDebugDescription=Badly formed object around line 2, column 18., NSJSONSerializationErrorIndex=20})))

However, all JSON validators I tried say that the JSON is valid and conforms to RFC 8259.

Swift doesn't let me to escape nested "{" and ”}" either.


The JSON format, unfortunately, is out of my control and I cannot alter it.

I also found this question, which looks similar, but nothing there works. Answers are relevant only for regular nested JSON objects. Or I missed something.

Any help is appreciated!

CodePudding user response:

The error is saying that the whole JSON isn't valid, not just the jsonString value.

While it's true that (you can test it in online validator like JSONLint for instance):

{
    "jsonString": "{\"someKey\": \"Some value\"}"
}

When declaring it as a String in Swift, you need to make sure that the backslashes are really present.

So it's:

let jsonString = """
{ "jsonString": "{\\"someKey\\": \\"Some value\\"}"}
"""

or

let jsonString = #"{"jsonString":"{\"someKey\": \"Some value\"}"}"#
  • Related