首页 > 解决方案 > 为什么我的 SwiftUI JSON 无法正确解析?

问题描述

免责声明:下面的另一个非常基本的问题。我正在努力学习IOS开发的基础知识。

我目前正在尝试将数据从 API 解析到 SwiftUI 项目,但无法成功。

代码如下:

import SwiftUI

struct Poem: Codable, Hashable {
    let title, author: String
    let lines: [String]
    let linecount: String
}


struct ContentView: View {
        
    var poems = [Poem]()
        
    var body: some View {
            VStack {
                if let poem = poems.first {
                    Button("Refresh") {getPoem()}
                    Text("\(poem.author): \(poem.title)").bold()
                    Divider()
                    ScrollView {
                        VStack {
                            ForEach(poem.lines, id: \.self) {
                                Text($0)
                            }
                        }
                    }
                }
            }
        }
}

func getPoem() {
    let url = URL(string: "https://poetrydb.org/random/1")!
    // 2.
    URLSession.shared.dataTask(with: url) {(data, response, error) in
        do {
            if let poemData = data {
                // 3.
                let decodedData = try JSONDecoder().decode([Poem].self, from: poemData)
                DispatchQueue.main.async {
                    self.poems = decodedData
                }
            } else {
                print("No data")
            }
        } catch {
            print("Error")
        }
    }.resume()
}

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

代码不构建。抛出的错误发生在 Func getPoem 中“无法在范围内找到'self'”。

有任何想法吗?感谢所有帮助。

标签: arraysjsonswiftswiftui

解决方案


我的意思是

class FetchPoem: ObservableObject {
  // 1.
  @Published var poems = [Poem]()
     
    init() {
        getPoem()
    }
    
    func getPoem() {
        let url = URL(string: "https://poetrydb.org/random/1")!
        // 2.
        URLSession.shared.dataTask(with: url) {(data, response, error) in
            do {
                if let poemData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode([Poem].self, from: poemData)
                    DispatchQueue.main.async {
                        self.poems = decodedData
                    }
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()
    }
}

struct PoemContentView: View {
        
    @ObservedObject var fetch = FetchPoem()
    
    var body: some View {
        VStack {
            Button("Get Next Poem") { fetch.getPoem() }
            if let poem = fetch.poems.first {
                Text("\(poem.author): \(poem.title)").bold()
                Divider()
                ScrollView {
                    VStack {
                        ForEach(poem.lines, id: \.self) {
                            Text($0)
                        }
                    }
                }
            } else {
                Spacer()
            }
        }
    }
}

推荐阅读