Reputation: 2246
Using Swift 4's Encoder
& Decoder
protocol and JSONDecoder
how do I initialize a struct of type Codeable
using a key from a given JSON.
i.e. Given the JSON below I wish to only use results
to initialize Example
{
"boolean": true,
"number": 123,
"results": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
struct Example: MDB, Codeable{
var a: String
var b: String
var c: String
}
public static func initalize<T: Codable & MDBItem>(json: Data) -> [T]{
var items = [T]()
let decoder = JSONDecoder()
do {
//How do I initialize `T` using a key from the JSON given
//ie. decoder.decode([T].self, from: json["results"])
// Or decoder.decode(["results", [T].self, from: json)
items = try decoder.decode([T].self, from: json)
} catch {
print("error trying to convert data to JSON")
}
return items
}
Upvotes: 2
Views: 632
Reputation: 59496
A possible easy way is creating a wrapper struct.
So, you have this JSON
let json = """
{
"boolean": true,
"number": 123,
"results": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
"""
Since you are only interested into the "results"
section you defined this struct
struct Example: Codable {
let a: String
let c: String
let e: String
}
Now in order to leverage the power of the Codable
protocol (available in Swift 4) you can create a wrapper struct like this
struct Wrapper: Codable {
let results: Example
}
The only purpose of the Wrapper struct is to define a path from the root of the original JSON to the section you are interested in. This was the
Codable
protocol will do the rest of the job for you.
Now you can use the Wrapper struct to easily decode the JSON.
if
let data = json.data(using: .utf8),
let wrapper = try? JSONDecoder().decode(Wrapper.self, from: data) {
let results = wrapper.results
print(results)
}
And finally you can extract the results
property from the wrapper.
Upvotes: 2