Reputation: 1226
I have a problem with a Codable parsing... that's my example code:
class Test: Codable {
let resultCount: Int?
let quote: String?
}
var json = """
{
"resultCount" : 42,
"quote" : "My real quote"
}
""".data(using: .utf8)!
var decoder = JSONDecoder()
let testDecoded = try! decoder.decode(Test.self, from: json)
Here everything works as expected and the Test object is created.
Now my back end sends me the quote string with a quote in the middle... in this form (please note \"real\"):
class Test: Codable {
let resultCount: Int?
let quote: String?
}
var json = """
{
"resultCount" : 42,
"quote" : "My \"real\" quote"
}
""".data(using: .utf8)!
var decoder = JSONDecoder()
let testDecoded = try! decoder.decode(Test.self, from: json)
In this second case the decoder fails to create the object... and that's my error message:
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 4." UserInfo={NSDebugDescription=No string key for value in object around character 4.})))
Is there a way to solve this issue?
Upvotes: 2
Views: 2358
Reputation: 437482
To include quotation marks in your JSON there have to be actual \
characters before the quotation marks within the string:
{
"resultCount" : 42,
"quote" : "My \"real\" quote"
}
To do that in Swift string literal, you need to escape the \
. That results in "My \\"real\\" quote"
within the Swift multi-line string literal:
let json = """
{
"resultCount" : 42,
"quote" : "My \\"real\\" quote"
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let testDecoded = try! decoder.decode(Test.self, from: json)
However, if dealing with a standard, non-multiline string literal, you need to escape both the backslash and the quotation mark, resulting in even more confusing looking \"My \\\"real\\\" quote\"
:
let json = "{\"resultCount\": 42, \"quote\" : \"My \\\"real\\\" quote\"}"
.data(using: .utf8)!
Upvotes: 2