Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get struct out of GEOSwift.JSON #265

Open
benpva16 opened this issue Jun 5, 2023 · 4 comments
Open

Get struct out of GEOSwift.JSON #265

benpva16 opened this issue Jun 5, 2023 · 4 comments

Comments

@benpva16
Copy link

benpva16 commented Jun 5, 2023

I have a GEOSwift feature like this:

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

I want to retrieve the data member and put it into a struct that matches:

struct MyStruct: Decodable {
    var id: Int
    var sizeClass: String?
    // and so on...
}

I can get the data, but the datatype is GEOSwift.JSON, and it's way too many properties to manually write all the code to do the conversion.

if case let .object(data) = feature.properties?["data"] {
  // how do I get data: GEOSwift.JSON converted to MyStruct?
}
@benpva16 benpva16 changed the title Convert GEOSwift.JSON to struct Get struct out of GEOSwift.JSON Jun 5, 2023
@macdrevx
Copy link
Member

macdrevx commented Jun 5, 2023

Hi @benpva16, thanks for sharing this use case. There are a few options here (some possible today, others that we'd need to build):

  • Option 1: Bypass GEOSwift to decode the properties from your GeoJSON features. You'd basically decode your JSON Data twice — once to get GEOSwift Features (assuming you need that too) and again to get just the properties represented as your custom struct. There's some wasted effort since the GEOSwift.JSON still gets created.
  • Option 2: re-serialize the GEOSwift.JSON to Data and then decode it again to your custom Codable struct. This is probably the easiest to write, but it might not be sufficiently performant depending on your use case.
  • Option 3: we build some kind of custom decoding capability that lets you pass in an arbitrary Codable type and a GEOSwift.JSON and it does the mapping automatically. This would likely be very similar in implementation & interface to JSONDecoder. This could potentially be more performant than options 1 and 2.
  • Option 4: make Feature.properties generic so you can define a custom type for it. I'd need to explore this more, but the generic type would likely propagate through several other types (at least FeatureCollection, GeoJSON). We'd also probably want some typealiases that hide it for folks who just want to use JSON.

Let me know what you think!

@benpva16
Copy link
Author

benpva16 commented Jun 5, 2023

I figured out option 3 just before you commented. You have to re encode feature.properties["data"] back to JSON, then decode it to MyStruct. You can't do this directly, so you encode it then decode 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)

Obviously, it'd be more straight forward to be able to just say

myStruct = try decoder.decode(MyStruct.self, from: feature.properties?["data"] ?? nil)

or something similar.

@benpva16 benpva16 closed this as completed Jun 5, 2023
@macdrevx
Copy link
Member

macdrevx commented Jun 6, 2023

Mind if we leave this open? I'd like to explore adding a solution like what you described

@macdrevx macdrevx reopened this Jun 6, 2023
@benpva16
Copy link
Author

benpva16 commented Jun 9, 2023

@macdrevx I don't mind at all, thank you for your consideration. If other solutions are added I would love to see what gets cooked up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants