简体   繁体   中英

How I can display datas on my screen swift

I am trying to display employee names, salaries, ages on the screen but it gives me "Initializer 'init(_:rowContent:)' requires that 'EmployeeData' conform to 'Identifiable'" error and "Undefined variable" error. How I can fix these and display datas. Thank u

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

There are multiple issues with this code, so let's look fix them step by step.

Step 1 - Fix build error

Your observed object is an array of EmployeeData which does not conform to the Identifiable protocol. This is an easy fix. In your FetchToDo class replace:

@Published var todos = [EmployeeData]()

with

@Published var todos = [Employee]()

Now the project builds, although the list is empty in the Preview and when you run it on the device.

Step 2 - Fetch the data

You need to observe your data source and then populate the list from the published employees property. It helps if the view actually loads the fetched data rather than static strings. And when the view appears, you can call the getData() function of the data source.

That isn't enough, because you need to create an exception to App Transport Security in your Info.plist file like this:

在此处输入图像描述

If you rewrite your code like this, it will work in the simulator.

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

You need to run your preview to see it working there. You can work around this with a bit more rewriting of your code but that's a much bigger question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM