1

This is the JSON I am trying to decode with Decodable protocol.

I have this error message:

Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unescaped control character around character 718.

let jsonData = """
{
    "pagination": {
        "per_page": 10,
        "previous_page": null,
        "total": 51,
        "next_page": 2,
        "current_page": 1
    },
    "collection": [
        {
            "id":408979,
            "asker_id":948560,
            "answer_id":"0c5e0296-6df8-47f0-8ebe-978cdfbaeb0d",
            "package_id":"00000000-0000-0000-0000-000000000000",
            "category_id":40,
            "address":"27 Boulevard Jean Rose, 77100 Meaux, France",
            "city":"Meaux",
            "created_at":"2019-12-16T11:25:44+01:00",
            "updated_at":"2019-12-16T11:25:44+01:00",
            "title":"voici le test de la demande",
            "description":"Titre : voici le test de la demande\nDescription : sdfghjhhhhhhhhhhhhhbvgnvh\nLocalisation : Meaux\nEst-ce pour une société ? : Non",
            "state":"open",
            "visibility":"public",
            "share_url":"https://dev.stoo.com/stoot/mission/voici-le-test-de-la-demande-408979",
            "shareUrl":"https://dev.stoo.com/stoot/mission/voici-le-test-de-la-demande-408979",
            "lat":"48.9616755",
            "lng":"2.8812038"
    }
]
}
""".data(using: .utf8)!

I've checked with and without the key description and this is the value associated which is the reason of the problem.

Here is my model:

struct Results : Decodable {
    struct Pagination : Codable {
        let total: Int

        enum CodingKeys : String, CodingKey {
            case total
        }
    }

    struct Collection : Decodable {
        let id: Int
    }

    let pagination: Pagination
    let collection: [Collection]
} 

let model = try! JSONDecoder().decode(PagedCompanies.self, from: jsonData)

This response comes from an API and there is no way to update it. How to update my model in order to correctly decode the json?

Community
  • 1
  • 1
kroko
  • 299
  • 3
  • 10
  • Have a look at [Swift JSONDecoder can't decode valid JSON with escape characters](https://stackoverflow.com/questions/57796640/swift-jsondecoder-cant-decode-valid-json-with-escape-characters). Your JSON String is invalid in Swift, you need to use `\\` in String literals instead of `\'`. That JSON should decode just fine when coming straight from a URLRequest rather than declaring it as a String. – Dávid Pásztor Dec 18 '19 at 10:40

1 Answers1

2

You can figure out the position 718 very quickly yourself:

  • Replace

    let jsonData = """
    
    ...
    
    """.data(using: .utf8)!
    

    with

    let jsonString = """
    
    ...
    
    """
    let jsonData = Data(jsonString.utf8)
    
  • Add

    let startIndex = jsonString.index(jsonString.startIndex, offsetBy: 718)
    print(jsonString[startIndex...])
    

    and run the code.

It reveals at once that the affected character is \n. In the literal multiline string syntax any backslash must be escaped with a second backslash

...
"description":"Titre : voici le test de la demande\\nDescription : sdfghjhhhhhhhhhhhhhbvgnvh\\nLocalisation : Meaux\\nEst-ce pour une société ? : Non"
...

If the data is coming from a server this error must not occur.

The structs are correct. You don't even need the CodingKeys for total.

vadian
  • 274,689
  • 30
  • 353
  • 361