Using URLSession to get crystal data from my custom API. Trying to list by title.
I know something's incorrect here but not sure what. Looked all over SO for JSON dictionary decoding but no luck.
Is a Response struct superfluous or can I simply decode [String:Crystal] with JSONDecoder()? Any and all direction and suggestion is appreciated. I knew how to do this with arrays but dictionaries are tripping me up.
GET https://lit-castle-74820.herokuapp.com/api/crystals
{
"amethyst": {
"composition": "silicon dioxide",
"formation": "forms when gas bubbles occur in lava and become trapped",
"colour": "purple",
"metaphysical": [
"calming",
"healing",
"especially for headaches",
"fatigue, & anxiety"
]
},
"clear quartz": {
"composition": "silicon dioxide",
"formation": "forms when gas bubbles occur in lava and become trapped",
"colour": "colourless or appears white",
"metaphysical": "master healer for all ailments; amplifies the healing vibration of other stones placed nearby"
},
"moss agate": {
"composition": "silicon dioxide, commonly featuring manganese or iron",
"formation": "formed from weathered volcanic rock",
"colour": "colourless with specks of white, green, blue, or brown",
"metaphysical": [
"gentle healing",
"promotes tranquility",
"cures physical ailments (inflammation, cold & flu)"
]
},
"carnelian": {
"composition": "silicon dioxide with iron impurity",
"formation": "formed from a combination of the silica minerals quartz and moganite",
"colour": "orange or red often featuring yellow",
"metaphysical": [
"promotes life-force",
"vitality",
"energizes body and mind"
]
},
"spirit quartz": {
"composition": "silicon dioxide",
"formation": "forms when gas bubbles occur in lava and become trapped",
"colour": "purple, yellowish brown, light grey",
"metaphysical": [
"assists in spiritual journey",
"uplifts and promotes vibration"
]
},
"amazonite": {
"composition": "potassium feldspar",
"formation": "formed in deep sea igneous rocks that cool very slowly",
"colour": "blue or green with white speckles or lines",
"metaphysical": [
"Soothes anxiety and overthinking",
"helps heal emotional trauma"
]
},
"tourmaline": {
"composition": "silicate of boron and aluminum",
"formation": "Pegmatite pockets underground that slowly cool and form crystals",
"colour": "black or pink",
"metaphysical": [
"repels negative energy",
"highly protective"
]
},
"pyrite": {
"composition": "iron sulfide",
"formation": "forms in sedimentary rocks in low oxygen environments",
"colour": "gold",
"metaphysical": [
"abundance",
"good luck",
"emotional strength"
]
}
}
struct Response: Codable {
let crystals: [String:Crystal]
}
struct Crystal: Codable, Identifiable {
var id = UUID()
let composition, formation, color: String
let metaphysical: [String]
}
struct ContentView: View {
@State private var crystals: [String:Crystal] = [:]
var body: some View {
List(crystals) { crystal in
(crystal.key)
}.onAppear(perform: loadData)
}
func loadData() {
guard let url = URL(string: "https://lit-castle-74820.herokuapp.com/api/crystals") else { return }
URLSession.shared.dataTask(with: url) { data, _, error in
guard let data = data else { return }
do {
let decodedResponse = try JSONDecoder().decode(Response.self, from: data)
DispatchQueue.main.async {
self.crystals = decodedResponse.crystals
}
} catch let jsonError as NSError {
print("JSON decode failed: \(jsonError)")
}
}.resume()
}
}