I am bringing data such as an user name from an API using Alamofire, I am trying to append the data I bring from the API to an array (users), and then, the numberOfRowsInSection in my table are the amount of items in the array, such as here:
var users: [User] = []
func getUser(){
AF.request("https://randomuser.me/api/?results=1", method: .get).validate(statusCode: statusOK).responseDecodable (of: UserResult.self){ response in
if let user = response.value?.results{
self.users = user
print(user)
// self.viewController.tableView.reloadData()
print(user.first?.name?.first! ?? "Unknown")
print(user.count)
} else {
print(response.error?.errorDescription ?? "No error")
}
}
}
But then, when I run the app there are no cells, so I print users.count in the viewDidLoad where the table is located, and it prints 0, but if I print users.count in the getUser() function, it actually prints that there is 1 item in the array, as in here:
0
[Random_User_List.User(name: Optional(Random_User_List.Name(first: Optional("Fredi"))), email: "[email protected]", gender: Optional("male"), address: nil, phone: Optional("0488-7393469"))]
Fredi
1
So I'm assuming I have to load the info inside the users array before summoning the getUsers() function in the viewDidLoad, and I have tried to use a reloadData() in both View Controller's viewDidLoad() and after catching the data inside the array, and it didn't work either, in fact, it caused a EXC_BAD_ACESS in networkingProvider (Thread 1: EXC_BAD_ACCESS (code=2, address=0x16cd37fc0)):
var networkingProvider = NetworkingProvider()
override func viewDidLoad() {
super.viewDidLoad()
NetworkingProvider.shared.getUser()
print(networkingProvider.users.count)
// self.tableView.reloadData()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "myCustomCell")
}
I will also leave my Model if that helps:
struct UserResult: Decodable{
let results: [User]?
}
struct User: Decodable{
var name: Name?
var email: String
var gender: String?
var address: String?
var phone: String?
}
struct Name: Decodable{
var first: String?
}
CodePudding user response:
func getUser(completion: @escaping (_ users:[User]?,_ error:Error?) -> Void){
AF.request("https://randomuser.me/api/?results=1", method: .get).validate(statusCode: statusOK).responseDecodable (of: UserResult.self){ response in
if let user = response.value?.results{
completion(user, nil) // if array other wise change the completion argument to single object
} else {
print(response.error?.errorDescription ?? "No error")
completion(nil, error)
}
}
}
and reload the table after getting user
override func viewDidLoad() {
super.viewDidLoad()
NetworkingProvider.shared.getUser { users, error in
if let users = users {
self.users = users
self.tableView.reloadData() // or you can use didSet of array to reload Data
}
}
}
Using didSet to reload
var users: [User] = [] {
didSet {
tableView.reloadData() // if you using this then you don't need to reload in viewdidload closure
}
}