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