Convert GEOSwift.JSON to struct in Swift
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",
// and so on...
},
"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...
}
This code will get me the data
alone, but the datatype is GEOSwift.JSON, and I don't know how to stringify it to decode using the usual JSONDecoder class.
if case let .object(data) = feature.properties?["data"] {
// do stuff with data: GEOSwift.JSON to get it into MyStruct
}
Here is the GEOSwift.JSON enum:
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()
}
}
}
extension JSON: ExpressibleByStringLiteral {
public init(stringLiteral value: String) {
self = .string(value)
}
}
extension JSON: ExpressibleByIntegerLiteral {
public init(integerLiteral value: Int) {
self = .number(Double(value))
}
}
extension JSON: ExpressibleByFloatLiteral {
public init(floatLiteral value: Double) {
self = .number(value)
}
}
extension JSON: ExpressibleByBooleanLiteral {
public init(booleanLiteral value: Bool) {
self = .boolean(value)
}
}
extension JSON: ExpressibleByArrayLiteral {
public init(arrayLiteral elements: JSON...) {
self = .array(elements)
}
}
extension JSON: ExpressibleByDictionaryLiteral {
public init(dictionaryLiteral elements: (String, JSON)...) {
let object = elements.reduce(into: [:]) { (result, element) in
result[element.0] = element.1
}
self = .object(object)
}
}
extension JSON: ExpressibleByNilLiteral {
public init(nilLiteral: ()) {
self = .null
}
}
Comments
Post a Comment