Home > Enterprise >  Push the data from the request into the array
Push the data from the request into the array

Time:02-06

I want to write the data that I received from the request into an array and then display it through a list

Here is my structure for the json file

struct DataRespons: Codable {
    
    let data: [String]
    let status: String
}

struct UserRespons: Codable {
    
    let status: String
    let data: UserData
}

struct UserData: Codable, Identifiable {
    
    let id: String
    let firstName: String
    let lastName: String
    let age: Int
    let gender: String
    let country: String
}

This is my class for JSON requests and decoding

import Foundation

@MainActor
class NetworkModel: ObservableObject {
    
    @Published var listId: [String] = []
    var statusList = ""
    var statusUser = ""
    var temp = ""
    var user: [UserData] = []     // here I am not sure if this type Array
    @Published var userData = UserRespons(status: "??", data: UserData(id: "???", firstName: "???", lastName: "??", age: 4, gender: "???", country: "???"))

this func for receive a letter with links to which I should make requests

func getList() {
        guard let url = URL(string: "https://opn-interview-service.nn.r.appspot.com/list") else { fatalError("Missing URL") }
        var request = URLRequest(url: url)
        request.addValue("bearer \(token)", forHTTPHeaderField: "Authorization")
        let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("Requst error",error)
                return
            }
            guard let response = response as? HTTPURLResponse else { return }
            if response.statusCode == 200 {
                guard let data = data else { return }
                DispatchQueue.main.async { [self] in
                    do {
                        let decoded = try JSONDecoder().decode(DataRespons.self, from: data)
                        self.listId = decoded.data
                        self.statusList = decoded.status
                        
                        for i in self.listId.indices {
                            print("This is id[\(i)] = \(listId[i])")
                            getUser(url: "\(listId[i])")
// #MARK: NEED HERE HELP          user.append(.init(id: <#T##String#>, firstName: <#T##String#>, lastName: <#T##String#>, age: <#T##Int#>, gender: <#T##String#>, country: <#T##String#>))
                        }
                    } catch let error{
                        print("Error decode",error)
                    }
                }
            }
        }
        dataTask.resume()
    }

I want to add data that will come from requests to an empty array so that it can then be displayed in the list

function for decoding data user

    func getUser(url: String) {
        guard let url = URL(string: "https://opn-interview-service.nn.r.appspot.com/get/\(url)") else { fatalError("Missing URL") }
        var request = URLRequest(url: url)
        request.addValue("bearer \(token)", forHTTPHeaderField: "Authorization")
        let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("Requst error",error)
                return
            }
            guard let response = response as? HTTPURLResponse else { return }
            if response.statusCode == 200 {
                guard let data = data else { return }
                DispatchQueue.main.async { [self] in
                    do {
                        let decoded = try JSONDecoder().decode(UserRespons.self, from: data)
                        self.userData = decoded
                        self.statusUser = decoded.status
                        print("UserData: name = \(userData.data.firstName) Lastname = \(userData.data.lastName) gender = \(userData.data.gender)")


                    } catch let error{
                        print("Error decode",error)
                    }
                }
            }
        }
        dataTask.resume()
    }

I don't know how to throw all the data into the array

CodePudding user response:

First of all iterating the indices is cumbersome, replace

for i in self.listId.indices {
    print("This is id[\(i)] = \(listId[i])")
    getUser(url: "\(listId[i])")

}

with

for id in self.listId {
    print("This is \(id)")
    getUser(url: id)
}

But this is not the right place to append the user data. Do it in getUser. But first declare the array as @Published (and in plural form)

 @Published var users = [UserData]()

and delete the property userData because it's not needed.

 @Published var userData = UserRespons(status: "??", data: UserData(id: "???", firstName: "???", lastName: "??", age: 4, gender: "???", country: "???"))

Now replace the decoding part in getUser with

let decoded = try JSONDecoder().decode(UserRespons.self, from: data)
self.statusUser = decoded.status
users.append(decoded.data)

print("UserData: name = \(decoded.data.firstName) Lastname = \(decoded.data.lastName) gender = \(decoded.data.gender)")

I recommend to move to async/await. It's much less code and it switches to the main thread automatically.

  • Related