Transform GEOSwift.JSON into a Swift struct

In my GEOSwift implementation, I have a feature structured like this:

{
  "type" : "Feature",
  "geometry" : {
    "type" : "Point",
    "coordinates" : [
      -xx.xxxxxxxxxxxxxxx,
      xx.xxxxxxxxxxxxxxx
    ]
  },
  "properties" : {
    "mapLayer" : "MyMapLayer",
    "data" : {
      "id" : 42,
      "sizeClass" : "Large",
    // and so on...
    },
    "featureType" : "MyFeatureType"
  }
}

My goal is to extract the data section and map it to a struct as follows:

struct MyStruct: Decodable {
    var id: Int
    var sizeClass: String?
    // and more properties...
}

This snippet of code above retrieves the data part, however, it is of type GEOSwift.JSON, and converting it into string to decode using JSONDecoder class is unclear.

if case let .object(data) = feature.properties?["data"] {
  // process data: GEOSwift.JSON to convert it into MyStruct
}

Below is the GEOSwift.JSON enum definition:

import Foundation

public enum JSON: Hashable, Sendable {
    case string(String)
    case number(Double)
    case boolean(Bool)
    case array([JSON])
    case object([String: JSON])
    case null

    /// Recursively unwraps and returns the associated value
    public var untypedValue: Any {
        switch self {
        case let .string(string):
            return string
        case let .number(number):
            return number
        case let .boolean(boolean):
            return boolean
        case let .array(array):
            return array.map { $0.untypedValue }
        case let .object(object):
            return object.mapValues { $0.untypedValue }
        case .null:
            return NSNull()
        }
    }

   // Additional extensions for JSON initialization
}

Answer №1

To convert feature.properties["data"] back to JSON and then decode it into MyStruct, you need to first encode it as GEOSwift.JSON does not conform to Decodable directly. However, it does conform to Encodable, so the process involves encoding it and then decoding it back.

let myStructData = feature.properties?["data"] ?? nil
let jsonData = try! JSONEncoder().encode(myStructData)
let decoder = JSONDecoder()
myStruct = try decoder.decode(MyStruct.self, from: jsonData)

Answer №2

In addition to the answer provided earlier, it is worth noting that the GEOSwift.JSON enum is encodable, allowing for direct conversion to JSON data using JSONEncoder. This eliminates the need for an intermediate step of converting GEOSwift.JSON to a dictionary and then to Data. The code snippet would look something like this:

import Foundation
import GEOSwift

struct MyStruct: Decodable {
    let id: Int
    let sizeClass: String
    // and so forth...
}

if let feature = mySomething as? GeoJSON.Feature {
    // Extract the properties as GEOSwift.JSON
    if let data = feature.properties?["data"] {
        do {
            // Re-encode GEOSwift.JSON back to JSON Data
            let jsonData = try JSONEncoder().encode(data)

            // Decode JSON Data into your struct
            let decoder = JSONDecoder()
            let myStruct = try decoder.decode(MyStruct.self, from: jsonData)

            // Utilize `myStruct`
            print(myStruct)
        } catch {
            print("Error: \(error)")
        }
    }
} else {
    // Handle other scenarios here
    print("GeoJSON object is not a Feature")
}

This method should work effectively as long as the structure of the GEOSwift.JSON object aligns with your MyStruct. If there is a mismatch in structure, errors will occur during the decoding process.


Alternatively, another option mentioned in the comments is to use MKGeoJSONDecoder which can be a suitable alternative to GEOSwift when working specifically with map-related data using Apple's MapKit framework.
This approach offers a convenient way to parse GeoJSON data and convert it into objects suitable for display on a map.

A basic example of how you could utilize MKGeoJSONDecoder for parsing GeoJSON data is outlined below:

import MapKit

// Assuming you have GeoJSON data stored in a variable named `geoJsonData` of type Data
let geoJsonObject: [MKGeoJSONObject]
do {
    geoJsonObject = try MKGeoJSONDecoder().decode(geoJsonData)
} catch {
    print("Failed to decode GeoJSON: \(error)")
    return
}

// You can then handle the geoJsonObject based on its type
for object in geoJsonObject {
    switch object {
    case let feature as MKGeoJSONFeature:
        // Process feature
        print("Feature: \(feature)")
    case let geometry as MKShape & MKGeoJSONObject:
        // Handle geometry
        print("Geometry: \(geometry)")
    default:
        print("Unexpected type")
    }
}

This snippet parses GeoJSON data and displays each feature or geometry present in the data. MKGeoJSONFeature objects contain details about the feature's properties which can be accessed via the properties property of type Data. Should your features include properties represented as JSON objects, the JSONDecoder can assist in decoding these properties into Swift types defined by you.

It is important to note that MKGeoJSONDecoder is tailored for use with the MapKit framework and intended for map-related data operations. For applications not involving maps or requiring processing of non-map-centric GeoJSON data, an alternative such as GEOSwift or a general-purpose GeoJSON library might be more suitable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The ng-repeat function is currently disabled and not displaying any data from the JSON object

I am currently facing an issue where the ng-repeat Directive in my code is getting commented out and not displaying the results of the JSON object. I have verified that the object is being properly passed to "this.paises2" using the toSource() method, and ...

Blogger's homepage URL obtained using JSON data

Please note: I don't have a background in programming. I'm making an effort to learn as much as possible. As I was reading (and later experimenting with) the solution to this query, it dawned on me that having the same information in JSON form ...

What is the process for incorporating a unique Mongo expression into a JSON object?

I'm currently trying to figure out how to add a specific Mongo command to my JSON object. Normally, adding regular strings or objects is straightforward, but I'm struggling with this particular command: $set : { "author" : req.body.name } Simpl ...

Guide to presenting JSON data with ajax

I am trying to dynamically display data based on the selected value from a drop-down list using Ajax's GET method. The idea is to modify the URL by appending the selected item in order to retrieve relevant data from the server: Here is an example of ...

The Echart bar graph is not displaying when trying to use JSON data

Seeking assistance as a beginner in building Basic Bar inverted axes using json data. I am trying to achieve a chart similar to Bar Inverted Axes, but encountering issues with the chart not displaying properly. Utilizing Angular to develop the web applicat ...

Strip away double quotation marks from object attributes except those beginning with a number

I've searched extensively and reviewed various Q&A forums, but I haven't encountered a scenario quite like this. Here's an example of the object I'm working with: props: { "label": "1rem", "text3": "1rem", "text2Button": "1re ...

Sorting JSON data in EJS based on categories

Hello, I am facing a dilemma. I need to apply category filtering to a JSON file but I am unsure of how to proceed with it. For instance, I wish to filter the 'vida' category along with its description and price. I seem to be stuck at this junctu ...

Utilize recursive and for loop methods for parsing JSON efficiently

I have a JSON file that requires parsing. I'm attempting to implement a recursive method for this task. The current JSON data is structured as shown below: Item 01 SubItem 01 InnerSubItem 01 Item 02 SubItem 01 InnerSubItem 01 Unfortunately, t ...

Implementing JSON methods in C# WebService to enable communication with external servers

Is it possible to integrate an asp.net web service written in C# into an HTML5/JavaScript website? The challenge is that the web service and client are located on different domains, requiring a cross-domain request. ...

Error Occurred while Uploading Images using Ajax HTML Editor with JSON Data

I am facing an issue with my AJAX HtmlEditorExtender, specifically when trying to upload an image. The error message I receive is as follows: JavaScript runtime error: Sys.ArgumentException: Cannot de-serialize. The data does not correspond to valid JSON. ...

Encountering a "Raphael is undefined" error message when working with Treant.js

I need help creating an organizational flow chart using treant.js. Below is my code snippet, but I'm encountering a 'Raphael is not defined' error that I can't seem to solve. Can someone please assist me with identifying the root cause ...

Using JavaScript to transform JSON information into Excel format

I have tried various solutions to my problem, but none seem to fit my specific requirement. Let me walk you through what I have attempted. function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) { //If JSONData is not an object then JSON.parse will ...

Sending information to a Flask application using AJAX

Currently, I am working on transferring URLs from an extension to a Flask app. The extension is able to access the current URL of the website. I have set up an AJAX request to connect to Flask, and the connection is successful. However, when trying to send ...

I need to change a website into a string so that I can analyze it with javascript. How can I do this?

Currently, I am in the process of creating a website for my video game servers. The admin tool we use outputs the current server status in a .json format as a large text string to this specific URL: My goal is to retrieve the entire text string from the p ...

use the fetch api to send a url variable

I'm struggling to pass a URL variable through the API fetch and I can't seem to retrieve any results. As a newcomer to Javascript, any help is greatly appreciated. //Get IP address fetch('https://extreme-ip-lookup.com/json/') .then(( ...

Strange issue encountered when utilizing Worklight along with XSL transformation on a JSON response

I'm facing an unusual issue that I can't seem to resolve. Here is an example of a JSON response that I am dealing with. "values": [ { "time": "2014-02-26T09:01:00+01:00", "data": [ "A", "B" ] }, // additional objec ...

Generate a flexible JSON array in VB.NET

Looking to generate a flexible array that can be converted into a JSON array for visualization with Morris charts. The usual approach in VB.NET is as follows: Dim xArray(2) xArray(0) = New With {Key .TradingDay = "Day1", .Seller1 = 1500, .Seller2 = 160 ...

Using jQuery to dynamically insert a table row with JSON data into dropdown menus

I'm working on a web form that includes a table where users can add rows. The first row of the table has dependent dropdowns populated with JSON data from an external file. Check out the code snippet below: // Function to add a new row $(function(){ ...

How can I convert an Array into a Dictionary using JavaScript?

Is there a clever method (perhaps using a map function) to restructure my data object from this: [ {id: 1, from: "1/1/2021", to: "1/2/2022"}, {id: 2, from: "1/3/2021", to: "1/4/2022"}, {id: 1, from: "1/5/2 ...

What are the steps to create a JSON file structured in a tree format?

Can you provide instructions on creating a JSON file in the following tree format? root child1 child11 child2 child21 child22 child3 child31 I am looking to generate a sample JSON file that adheres to the ...