首页 > 解决方案 > 如何在屏幕上快速显示数据

问题描述

我正在尝试在屏幕上显示员工姓名、薪水、年龄,但它给了我“Initializer 'init(_:rowContent:)' 要求 'EmployeeData' 符合 'Identifiable'”错误和“未定义变量”错误。我如何修复这些并显示数据。感谢你

struct EmployeeData: Codable {
    var data: [Employee]
    var status: String
}

struct Employee: Codable, Identifiable {
    var id: String
    var employee_name: String
    var employee_salary: String
    var employee_age: String
}

class FetchToDo: ObservableObject {

    @Published var todos = [EmployeeData]()
    func getData(completion: @escaping (EmployeeData) -> ()){

        let url = URL(string: "http://dummy.restapiexample.com/api/v1/employees")!
        // 2.
        URLSession.shared.dataTask(with: url) {(data, response, error) in
            do {
                if let todoData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode(EmployeeData.self, from: todoData)

                    DispatchQueue.main.async{
                        completion(decodedData)
                    }

                    print(decodedData)
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()

    }
}
struct ContentView: View {
    // 1.
    @ObservedObject var fetch = FetchToDo()

    var body: some View {
        VStack {
            // 2.
            List(fetch.todos) { todo in
                VStack{
                    // 3.
                    Text("Hello")
                    Text("he")
                    Text("Eh")
                }
            }
        }
    }
}

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

标签: iosswift

解决方案


此代码存在多个问题,因此让我们逐步解决它们。

第 1 步 - 修复构建错误

您观察到的对象是一个EmployeeData不符合Identifiable协议的数组。这是一个简单的修复。在您的 FetchToDo 类中替换:

@Published var todos = [EmployeeData]()

@Published var todos = [Employee]()

现在项目构建了,尽管在预览中和在设备上运行它时列表是空的。

第 2 步 - 获取数据

您需要观察您的数据源,然后从发布的employees属性中填充列表。如果视图实际加载获取的数据而不是静态字符串,它会有所帮助。而当视图出现时,就可以调用getData()数据源的函数了。

这还不够,因为您需要在 Info.plist 文件中为 App Transport Security 创建一个例外,如下所示:

在此处输入图像描述

如果你像这样重写你的代码,它将在模拟器中工作。

import SwiftUI

struct EmployeeData: Codable {
    var data: [Employee]
    var status: String
}

struct Employee: Codable, Identifiable {
    var id: String
    var employee_name: String
    var employee_salary: String
    var employee_age: String
}

class EmployeeDataSource: ObservableObject {

    @Published var employees = [Employee]()

    func getData(){

        let url = URL(string: "http://dummy.restapiexample.com/api/v1/employees")!
        // 2.
        URLSession.shared.dataTask(with: url) {(data, response, error) in
            do {
                if let todoData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode(EmployeeData.self, from: todoData)

                    DispatchQueue.main.async{
                        self.employees = decodedData.data
                    }

                    print(decodedData)
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()

    }
}

struct ContentView: View {
    @ObservedObject var dataSource = EmployeeDataSource()

    var body: some View {
        List(dataSource.employees) { employee in
            VStack(alignment: .leading){
                Text(employee.employee_name)
                Text(employee.employee_salary)
            }
        }.onAppear { self.dataSource.getData() }
    }
}

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

您需要运行预览才能看到它在那里工作。您可以通过更多地重写您的代码来解决这个问题,但这是一个更大的问题。


推荐阅读