Home > Net >  Why am I having trouble with decoding JSON?
Why am I having trouble with decoding JSON?

Time:12-09

I do not understand why I am unable to decode my JSON file. Xcode keeps stating that they cannot find 'DogSection' in scope.

This is where the problem is:

let dog = Bundle.main.decode([DogSection].self, from: "dogData")

I am trying to get the dog data from the dog swift file then decode that file in my content view in order to have it show up on my app. In this code I have a list of dog names and when they are tapped, the image and description of the dog show up.

Here is my code: **content view: **

import SwiftUI

let dog = Bundle.main.decode([DogSection].self, from: "dogData")

struct DutchDetail: View {
    var body: some View {
        ForEach(dog) { section in
            NavigationLink(destination: { ForEach(section.description) { item in
                HStack{
                    Image("dutch_shepherd")
                    Text(section.name)
                }
                
            }
                
            }) {
                Text(section.name)
            }
            
        }
    }
}

struct HavaneseDetail: View {
    var body: some View {
        List {
            VStack (alignment: .leading){
                Text("Towel")
                Text("Phone Charger")
                Text ("Remote Control")
            }
        }
    }
}

struct ScottishDetail: View {
    var body: some View {
        List {
            VStack (alignment: .leading){
                Text("Jump Rope")
                Text("Dumbbell")
                Text ("Kettlebell")
            }
        }
    }
}

struct TosaDetail: View {
    var body: some View {
        List {
            VStack (alignment: .leading){
                Text("Pizza")
                Text("Yogurt")
                Text ("Sandwich")
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: DutchDetail()) {
                    HStack{
                        Image("dutch_shepherd")
                            .resizable()
                            .scaledToFit()
                        Text("Dutch Shepherd")
                    }
                }
                
                NavigationLink(destination: HavaneseDetail()) {
                    HStack {
                        Image("havanese")
                            .resizable()
                            .scaledToFit()
                        Text("Havanese")
                    }
                }
                NavigationLink(destination: ScottishDetail()) {
                    HStack {
                        Image("scottish_terrier")
                            .resizable()
                            .scaledToFit()
                        Text("Scottish Terrier")
                    }
                }
                NavigationLink(destination: TosaDetail()) {
                    HStack {
                        Image("tosa")
                            .resizable()
                            .scaledToFit()
                        Text("Tosa")
                    }
                    }
                }.navigationTitle("Alisson's Dog List")
            }
        }
    }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

**dog swift file: **

import SwiftUI

struct DogSection : Codable, Identifiable {
    var id: String
    var name: String
    var description: String
    var imageName: String
}

decode (helper)

import UIKit

extension Bundle {
    func decode<T: Decodable>(_ type: T.Type, from file: String) -> T {
        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate \(file) in bundle.")
        }

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")
        }

        let decoder = JSONDecoder()

        guard let loaded = try? decoder.decode(T.self, from: data) else {
            fatalError("Failed to decode \(file) from bundle.")
        }

        return loaded
    }
}

**dog data: **

[
    {
        "id": "aa32jj887hhg55",
        "name": "Airedale Terrier",
        "description": "The Airedale stands among the world's most versatile dog breeds and has distinguished himself as hunter, athlete, and companion.",
        "imageName": "airedale_terrier"
    },
    {
        "id": "bb32jj887hhg77",
        "name": "American Foxhound",
        "description": "American Foxhounds are good-natured, low-maintenance hounds who get on well with kids, dogs, even cats, but come with special considerations for prospective owners.",
        "imageName": "american_foxhound"
    },
    {
        "id": "cc32jj887hhg66",
        "name": "Dutch Shepherd",
        "description": "The Dutch Shepherd is a lively, athletic, alert and intelligent breed, and has retained its herding instinct for which it was originally developed.",
        "imageName": "dutch_shepherd"
    },
    {
        "id": "dd32jj887hhg88",
        "name": "Havanese",
        "description": "Havanese, the only dog breed native to Cuba, are vivacious and sociable companions and are especially popular with American city dwellers.",
        "imageName": "havanese"
    },
    {
        "id": "ee32jj887hhg99",
        "name": "Leoberger",
        "description": "The Leonberger is a lush-coated giant of German origin. They have a gentle nature and serene patience and they relish the companionship of the whole family.",
        "imageName": "leonberger"
    },
    {
        "id": "ff32jj887hhg99",
        "name": "Mudi",
        "description": "The Mudi is an extremely versatile, intelligent, alert, agile, all-purpose Hungarian farm dog. The breed is a loyal protector of property and family members without being overly aggressive.",
        "imageName": "mudi"
    },
    {
        "id": "gg32jj887hhg99",
        "name": "Norwegian",
        "description": "From Norway’s rocky island of Vaeroy, the uniquely constructed Norwegian Lundehund is the only dog breed created for the job of puffin hunting. With puffins now a protected species, today’s Lundehund is a friendly, athletic companion.",
        "imageName": "norwegian_lundehund"
    },
    {
        "id": "hh32jj887hhg99",
        "name": "Pharaoh Hound ",
        "description": "The Pharaoh Hound, ancient \"Blushing Dog\" of Malta, is an elegant but rugged sprinting hound bred to course small game over punishing terrain. Quick and tenacious on scent, these friendly, affectionate hounds settle down nicely at home.",
        "imageName": "pharaoh_hound"
    },
    {
        "id": "ii32jj887hhg99",
        "name": "Scottish Terrier",
        "description": "A solidly compact dog of vivid personality, the Scottish Terrier is an independent, confident companion of high spirits. Scotties have a dignified, almost-human character.",
        "imageName": "scottish_terrier"
    },
    {
        "id": "jj32jj887hhg99",
        "name": "Tosa",
        "description": "A solidly compact dog of vivid personality, the Scottish Terrier is an independent, confident companion of high spirits. Scotties have a dignified, almost-human character.",
        "imageName": "tosa"
    }
]

CodePudding user response:

(withExtension: "json") maybe you forgot to write file extension bellow

extension Bundle {
    func decode<T: Decodable>(_ type: T.Type, from file: String) -> T {
        guard let url = self.url(forResource: file, withExtension: "json") else {
            fatalError("Failed to locate \(file) in bundle.")
        }

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")
        }

        let decoder = JSONDecoder()

        guard let loaded = try? decoder.decode(T.self, from: data) else {
            fatalError("Failed to decode \(file) from bundle.")
        }

        return loaded
    }
}

CodePudding user response:

Change your in decode function like this

func decode<T: Codable>(_ file: String) -> T 

{Code will be same}

after that decode the file with this line

let dog: [DogSection] = Bundle.main.decode(“dogdata.json")

also change the range of second foreach loop with decoded data

NavigationLink(destination: { ForEach(dog) { item in
final contentview will be:
let dog: [DogSection] = Bundle.main.decode("dogdata.json")
struct DutchDetail: View {
    var body: some View {
        ForEach(dog) { section in
            NavigationLink(destination: { ForEach(dog) { item in
                HStack {
                    Image("dutch_shepherd")
                    Text(item.name)
                }
            }
            }) {
                Text(section.name)
            }
        }
    }
}

now you’re able to decode your json file and arrange that data as per your requirement.

  • Related