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.