I want to return Pokemon names from PokeApi, but I have this error : Value of type 'ListViewController.Pokemon' has no subscripts.
Here's my code :
import UIKit
class ListViewController: UIViewController {
@IBOutlet weak var pokemon1: UILabel!
@IBOutlet weak var pokemon2: UILabel!
@IBOutlet weak var pokemon3: UILabel!
@IBOutlet weak var pokemon4: UILabel!
@IBOutlet weak var pokemon5: UILabel!
let url = "https://pokeapi.co/api/v2/pokemon"
override func viewDidLoad() {
super.viewDidLoad()
fetchData(from: url)
}
func fetchData(from url: String) {
let url = URL(string: url)
let defaultSession = URLSession(configuration: .default)
let dataTask = defaultSession.dataTask(with: url!) { (data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print(String(describing: error))
return
}
var json: Pokemon
do {
json = try JSONDecoder().decode(Pokemon.self, from: data!)
Swift.print(json)
DispatchQueue.main.async {
// self.pokemon1.text = json[0].name
self.pokemon2.text = json[1].results.name
// self.pokemon3.text = json[0].results.name
// self.pokemon4.text = json[3].name
// self.pokemon5.text = json[4].name
//callback: fonction que j'appelle à la suite d'un évènement
}
} catch {
print(error)
return
}
}
dataTask.resume() // Commence la dataTask si elle n'est pas en marche actuellement
}
struct Pokemon: Codable {
let results: [Result]
}
struct Result: Codable {
let name: String
let url: String
}
}
I checked with the print and I am receiving the json data. here's what's in the print :
Pokemon(results: [RattrapageIOS.ListViewController.Result(name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon/1/"), RattrapageIOS.ListViewController.Result(name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon/2/"), RattrapageIOS.ListViewController.Result(name: "venusaur", url: "https://pokeapi.co/api/v2/pokemon/3/"), RattrapageIOS.ListViewController.Result(name: "charmander", url: "https://pokeapi.co/api/v2/pokemon/4/"), RattrapageIOS.ListViewController.Result(name: "charmeleon", url: "https://pokeapi.co/api/v2/pokemon/5/"), RattrapageIOS.ListViewController.Result(name: "charizard", url: "https://pokeapi.co/api/v2/pokemon/6/"), RattrapageIOS.ListViewController.Result(name: "squirtle", url: "https://pokeapi.co/api/v2/pokemon/7/"), RattrapageIOS.ListViewController.Result(name: "wartortle", url: "https://pokeapi.co/api/v2/pokemon/8/"), RattrapageIOS.ListViewController.Result(name: "blastoise", url: "https://pokeapi.co/api/v2/pokemon/9/"), RattrapageIOS.ListViewController.Result(name: "caterpie", url: "https://pokeapi.co/api/v2/pokemon/10/"), RattrapageIOS.ListViewController.Result(name: "metapod", url: "https://pokeapi.co/api/v2/pokemon/11/"), RattrapageIOS.ListViewController.Result(name: "butterfree", url: "https://pokeapi.co/api/v2/pokemon/12/"), RattrapageIOS.ListViewController.Result(name: "weedle", url: "https://pokeapi.co/api/v2/pokemon/13/"), RattrapageIOS.ListViewController.Result(name: "kakuna", url: "https://pokeapi.co/api/v2/pokemon/14/"), RattrapageIOS.ListViewController.Result(name: "beedrill", url: "https://pokeapi.co/api/v2/pokemon/15/"), RattrapageIOS.ListViewController.Result(name: "pidgey", url: "https://pokeapi.co/api/v2/pokemon/16/"), RattrapageIOS.ListViewController.Result(name: "pidgeotto", url: "https://pokeapi.co/api/v2/pokemon/17/"), RattrapageIOS.ListViewController.Result(name: "pidgeot", url: "https://pokeapi.co/api/v2/pokemon/18/"), RattrapageIOS.ListViewController.Result(name: "rattata", url: "https://pokeapi.co/api/v2/pokemon/19/"), RattrapageIOS.ListViewController.Result(name: "raticate", url: "https://pokeapi.co/api/v2/pokemon/20/")])
What seems to be the issue ?
CodePudding user response:
You are trying to access the Pokemon
type and get it's name, but name
is a property of the Result
type, instances of which are in the results array. What you want is:
json.results[0].name
to get the name of the first item in the array. If you used more informative names for your types the issue would have been more obvious. eg.
struct Wrapper: Codable {
let results: [Pokemon]
}
struct Pokemon: Codable {
let name: String
let url: String
}
}
and then you'd need
let wrapped = try JSONDecoder().decode(Wrapper.self, from: data!)
let pokemons = wrapped.results
//etc
self.pokemon2.text = pokemons[0].name