I started to work with API and got some problems that I'm not able to fix.
That's code related to my problem:
// MARK: - ProPlayerElement
struct ProPlayerElement: Codable {
let name, avatarfull, personaname: String?
let fantasyRole: Int?
let teamName: String?
enum CodingKeys: String, CodingKey {
case name, avatarfull, personaname
case fantasyRole = "fantasy_role"
case teamName = "team_name"
}
}
typealias ProPlayers = [ProPlayerElement]
class ApiManager {
static let shared = ApiManager()
func getInformation(completion: @escaping (ProPlayers) -> Void) {
let request = ApiType.proPlayers.request
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data, let players = try?JSONDecoder().decode(ProPlayers.self, from: data) {
completion(players)
} else {
completion([])
}
}
task.resume()
}
}
var heroNames = [String] ()
func heroesNames () {
ApiManager.shared.getInformation { players in
for i in 0..<players.count-1 {
self.heroNames.append(players[i].name!)
}
}
}
So, about the problem: when i use the last function (heroesNames) my variable doesn't save any info as if this function never existed at all.
I did some test and now I know that everything inside
ApiManager.shared.getInformation { ProPlayers in
}
works perfect but outside this expression zero results
added print((self.heroNames)) (and changed count-1, it was misprint) before append and after append, works fine
func heroesNames () {
ApiManager.shared.getInformation { players in
for i in 0..<players.count {
print("before append\(self.heroNames)")
self.heroNames.append(players[i].name!)
print("after append\(self.heroNames)")
}
}
}
before append[] after append["TZY"] before append["TZY"] after append["TZY", "YrikGood"] before append["TZY", "YrikGood"] after append["TZY", "YrikGood", "Newsham"]
try something like this, to deal with your asynchronous func heroesNames(...)
:
func heroesNames(completion: @escaping ([String]) -> Void) { // <-- here
ApiManager.shared.getInformation { players in
completion(players.map{$0.name}) // <-- here
}
}
And use it like this:
heroesNames() { names in
print("\(names.count)") // for testing
self.heroNames = names // <-- only here, not before
// alternatively
// self.heroNames.append(contentsOf: names)
}
Of course, you could do away with func heroesNames(...)
and use this instead:
ApiManager.shared.getInformation { players in
self.heroNames = players.map{$0.name}
}