为什么我有解码JSON的麻烦?



我不明白为什么我无法解码我的JSON文件。Xcode一直声明在scope中找不到'DogSection'

这就是问题所在:

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

我试图从狗swift文件中获取狗数据,然后在我的内容视图中解码该文件,以便让它显示在我的应用程序上。在此代码中,我有一个狗名字列表,当它们被点击时,狗的图像和描述显示出来。

下面是我的代码:**内容视图:**
import SwiftUI
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.description)
}
}
}) {
Text(section.name)
}
}
}
}
struct HavaneseDetail: View {
var body: some View {
List {
VStack (alignment: .leading){
Text("Havanese, the only dog breed native to Cuba, are vivacious and sociable companions and are especially popular with American city dwellers.")
}
}
}
}
struct ScottishDetail: View {
var body: some View {
List {
VStack (alignment: .leading){
Text("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.")
}
}
}
}
struct TosaDetail: View {
var body: some View {
List {
VStack (alignment: .leading){
Text("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.")
}
}
}
}
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("Dog List")
.foregroundColor(.red)
}
}
}
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
}

解码(助手)

import UIKit
extension Bundle {
func decode<T: Codable>(_ 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
}
}

**狗数据:**

[
{
"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"
}
]

像这样改变你的in decode函数

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

{代码相同}

之后用这行

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

还改变了使用解码数据的第二个foreach循环的范围

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)
}
}
}
}

现在你可以解码你的json文件,并按照你的要求安排数据。

(witheextension: "json")也许你忘了写文件扩展名

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
}
}

最新更新