MKGeoJSONDecoder can't parse escaped Double-Quote characters

When parsing valid GeoJSON data containing escaped double-quotes, the MKGeoJSONDecoder fails with error.


Steps to reproduce:

Download and copy the GeoJSON from the Berlin city API server into a String: https://www.berlin.de/sen/web/service/liefer-und-abholdienste/index.php/index/all.gjson?q=&plz=10117&art=B%C3%BCrobedarf&ipp=20&page=1

OR
use the following GeoJSON data


{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          13.38678,
          52.52548
        ]
      },
      "properties": {
        "title": "1848",
        "href": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848",
        "description": " <a href=\"/sen/web/service/liefer-und-abholdienste/index.php/detail/1848\">Mehr...</a>",
        "id": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848"
      }
    }
  ]
}
  1. Create a Data object from the string using .utf8 format
  2. Create a MKGeoJSONDecoder object
  3. Try and parse the data using `try decoder.decode(data)` in a do..catch block
  4. The catch block will report an error saying: “The data couldn’t be read because it isn’t in the correct format.”


If we change the description string and remove the escaped double-quotes `“\`, the MKGeoJSONDecoder decodes the data without issue.


The following code block when executed on a playground should show the error:

//Valid data verifed using http://geojson.io

    if let data = """
            {
                "features": [
                    {
                        "geometry": {
                            "coordinates": [
                                13.38678,
                                52.52548
                            ],
                            "type": "Point"
                        },
                        "properties": {
                            "description": " \" text in double quotes \" ",
                            "href": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848",
                            "id": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848",
                            "title": "1848"
                        },
                        "type": "Feature"
                    }
                ],
                "type": "FeatureCollection"
            }
        """.data(using: .utf8) {
        let decoder = MKGeoJSONDecoder()
        do {
            let decoded = try decoder.decode(data)
            if let firstFeature = decoded.first as? MKGeoJSONFeature,
                let firstCoordinate = firstFeature.geometry.first?.coordinate {
                print("Latitude: \(firstCoordinate.latitude) Longitude : \(firstCoordinate.longitude)")
            }
           
        } catch (let error) {
            print(error.localizedDescription)
        }
    }

Replies

You have some mistake in creating a Swift String representaion of the GeoJSON.

Please try this:

if let data = #"""
        {
            "features": [
                {
                    "geometry": {
                        "coordinates": [
                            13.38678,
                            52.52548
                        ],
                        "type": "Point"
                    },
                    "properties": {
                        "description": " \" text in double quotes \" ",
                        "href": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848",
                        "id": "/sen/web/service/liefer-und-abholdienste/index.php/detail/1848",
                        "title": "1848"
                    },
                    "type": "Feature"
                }
            ],
            "type": "FeatureCollection"
        }
    """#.data(using: .utf8) {
    let decoder = MKGeoJSONDecoder()
    do {
        let decoded = try decoder.decode(data)
        if let firstFeature = decoded.first as? MKGeoJSONFeature,
            let firstCoordinate = firstFeature.geometry.first?.coordinate {
            print("Latitude: \(firstCoordinate.latitude) Longitude : \(firstCoordinate.longitude)")
        }
         
    } catch {
        print(error)
    }
}