Having a slight trouble in saving my decoded JSON data into the struct, not sure what I'm doing wrong here.
What I'm trying to do is call the sneaker database and retrieve the results and display them in a view, i can see the JSON call is working with the print but now stuck on how to get this in a way I can display it into a view.
JSON
{
"count": 1,
"results": [
{
"id": "029ddc1d-a64b-469b-b9df-bd21c84a608e",
"brand": "Jordan",
"colorway": "Deep Ocean/Sail-Cement Grey-Fire Red",
"gender": "men",
"name": "SE Sashiko",
"releaseDate": "2020-12-05",
"retailPrice": 190,
"shoe": "Jordan 4 Retro",
"styleId": "CW0898-400",
"title": "Jordan 4 Retro SE Sashiko",
"year": 2020,
"media": {
"imageUrl": "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=700&h=500&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370",
"smallImageUrl": "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=300&h=214&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370",
"thumbUrl": "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=140&h=100&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370"
}
}
]
}
Model:
struct APIResponse: Decodable {
enum CodingKeys: String, CodingKey {
case shoeResults = "results"
}
let shoeResults: [Shoe]
}
struct Shoe: Decodable {
public var id: String
public var brand: String
public var colorway: String
public var gender: String
public var name: String
public var releaseDate: String
public var retailPrice: Int
public var shoe: String
public var styleId: String
public var title: String
public var year: Int
public var media: mediaData
enum CodingKeys: String, CodingKey {
case id = "id"
case brand = "brand"
case colorway = "colorway"
case gender = "gender"
case name = "name"
case releaseDate = "releaseDate"
case retailPrice = "retailPrice"
case shoe = "shoe"
case styleId = "styleId"
case title = "title"
case year = "year"
case media = "media"
}
}
struct mediaData: Decodable {
var imageUrl: String
var smallImageUrl: String
var thumbUrl: String
}
Shoefetcher class:
public class ShoeFetcher: ObservableObject {
init(){
load()
}
func load() {
let url = URL(string: "https://api.thesneakerdatabase.com/v1/sneakers?limit=10&styleId=cw0898-400")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decodedLists = try JSONDecoder().decode(APIResponse.self, from: d)
DispatchQueue.main.async {
print(decodedLists)
}
}else {
print("No Data")
}
}catch DecodingError.keyNotFound(let key, let context) {
Swift.print("could not find key \(key) in JSON: \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
Swift.print("could not find type \(type) in JSON: \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
Swift.print("type mismatch for type \(type) in JSON: \(context.debugDescription)")
} catch DecodingError.dataCorrupted(let context) {
Swift.print("data found to be corrupted in JSON: \(context.debugDescription)")
} catch let error as NSError {
NSLog("Error in read(from:ofType:) domain= \(error.domain), description= \(error.localizedDescription)")
}
}.resume()
}
}
output of decodedlists:
APIResponse(shoeResults: [Sneakers.Shoe(id: "029ddc1d-a64b-469b-b9df-bd21c84a608e", brand: "Jordan", colorway: "Deep Ocean/Sail-Cement Grey-Fire Red", gender: "men", name: "SE Sashiko", releaseDate: "2020-12-05", retailPrice: 190, shoe: "Jordan 4 Retro", styleId: "CW0898-400", title: "Jordan 4 Retro SE Sashiko", year: 2020, media: SneakerNews.mediaData(imageUrl: "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=700&h=500&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370", smallImageUrl: "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=300&h=214&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370", thumbUrl: "https://images.stockx.com/images/Air-Jordan-4-Retro-SE-Deep-Ocean-Product.jpg?fit=fill&bg=FFFFFF&w=140&h=100&auto=format,compress&trim=color&q=90&dpr=2&updated_at=1609439370"))])
Edit:
updated the shoefetcher class:
public class ShoeFetcher: ObservableObject {
@Published var shoeResults: [Shoe] = [] //added
init(){
load()
}
func load() {
let url = URL(string: "https://api.thesneakerdatabase.com/v1/sneakers?limit=10&styleId=cw0898-400")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decodedLists = try JSONDecoder().decode(APIResponse.self, from: d)
DispatchQueue.main.async {
self.shoeResults = decodedLists.shoeResults //added
print(self.shoeResults)
}
}else {
print("No Data")
}
}catch DecodingError.keyNotFound(let key, let context) {
Swift.print("could not find key \(key) in JSON: \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
Swift.print("could not find type \(type) in JSON: \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
Swift.print("type mismatch for type \(type) in JSON: \(context.debugDescription)")
} catch DecodingError.dataCorrupted(let context) {
Swift.print("data found to be corrupted in JSON: \(context.debugDescription)")
} catch let error as NSError {
NSLog("Error in read(from:ofType:) domain= \(error.domain), description= \(error.localizedDescription)")
}
}.resume()
}
}
added a ContentView to just see if I can display something off the JSON file.
struct ContentView: View {
@ObservedObject var fetcher = ShoeFetcher()
@State var Shoes: Shoe
var body: some View {
VStack {
Text("Shoes")
Text(Shoes.brand)
}
}
}
errors I'm getting is Missing argument for a parameter 'Shoes' in call in my SneakersApp.swift file
import SwiftUI
@main
struct SneakersApp: App {
var body: some Scene {
WindowGroup {
ContentView() //error here
}
}
}
I have a feeling I need to initialise the JSON variables but cant seem to workout where/how I do that