ios - 从公共(public) API 获取 JSON 以在 SwiftUI 的 ListView 中呈现

标签 ios swiftui xcode11 swift5 swiftui-list

我正在尝试从 Rest Api 获取数据,以下载并在 SwiftUI 中的 ListView 中呈现。 我想我设法让 JSON 下载并正确分配给所有相关的结构,但当我去构建它时,模拟器上的 ListView 中没有显示任何内容。

我什至不确定我是否需要在其中包含“Enum CodingKeys”。

有人能指出我可能出错的地方吗?

import Foundation
import SwiftUI
import Combine


struct ContentView: View {
    @ObservedObject var fetcher = LaunchDataFetcher()

    var body: some View {
        VStack {
            List(fetcher.launches) { launch in
                VStack (alignment: .leading) {
                    Text(launch.mission_name)
                    Text(launch.details)
                        .font(.system(size: 11))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

public class LaunchDataFetcher: ObservableObject {

    @Published var launches = [launch]()
    init(){
        load()
    }

    func load() {
        let url = URL(string: "https://api.spacexdata.com/v3/launches")!
        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let d = data {
                    let decodedLists = try JSONDecoder().decode([launch].self, from: d)
                    DispatchQueue.main.async {
                        self.launches = decodedLists
                    }
                }else {
                    print("No Data")
                }
            } catch {
                print ("Error")
            }

        }.resume()

    }
}

struct launch: Codable {
    public var flight_number: Int
    public var mission_name: String
    public var details: String

    enum CodingKeys: String, CodingKey {
           case flight_number = "flight_number"
           case mission_name = "mission_name"
           case details = "details"
        }
}

// Now conform to Identifiable
extension launch: Identifiable {
    var id: Int { return flight_number }
}


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

最佳答案

首先,我尝试找出代码中的哪个错误,并识别出某处响应数据的 launch.details 为空。这样我只需将此属性标记为可选即可工作。

更多详情,您可以引用以下代码:

struct launch: Codable {
    public var flight_number: Int
    public var mission_name: String
    public var details: String?

    enum CodingKeys: String, CodingKey {
           case flight_number = "flight_number"
           case mission_name = "mission_name"
           case details = "details"
        }
}

在捕获行,获取错误消息以准确了解发生了什么

func load() {
        let url = URL(string: "https://api.spacexdata.com/v3/launches")!
        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let d = data {
                    let decodedLists = try JSONDecoder().decode([launch].self, from: d)
                    DispatchQueue.main.async {
                        print(decodedLists)
                        self.launches = decodedLists
                    }
                }else {
                    print("No Data")
                }
            } catch let parsingError {
                print ("Error", parsingError)
            }

        }.resume()
    }

希望这有帮助!

关于ios - 从公共(public) API 获取 JSON 以在 SwiftUI 的 ListView 中呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59150196/

相关文章:

objective-c - 从文本中获取 URL

objective-c - 在 View Controller 之间传递字典

javascript - 错误 : Cannot read property 'push' of undefined React Native

swiftui - 多级导航 SwiftUI

ios - SwiftUI 和 UIKit 与旧 API 中的 UIViewController 要求交互

ios - Xcode 11 向后兼容性 : "UIWindowScene is only available in iOS 13 or newer"

ios - 在 iOS 7 中搜索显示 Controller 。出现键盘时缺少栏

swift - 时间和日期格式化程序 SwiftUI JSON 数据

swift - 下载图像后在 SwiftUI 中更新 ImageView

swift - UISegmentedControl iOS 13 SelectedTint 默认颜色