Arian Abbaszadeh
Arian Abbaszadeh

Reputation: 43

How to make API call in swiftUI

I am trying to use PokeApi to make a Pokedex app. I just started swift a couple of days ago so I'm following a tutorial here: https://www.youtube.com/watch?v=UsO-84Xnhww. The tutorial doesn't seem to work, and I don't know how to access the PokeAPI in order to make this app. My code is posted below:

ContentView:

import SwiftUI

struct ContentView: View {
    @State var searchText = ""
    var pokemon = [Pokemon]()
    
    var body: some View {
        
        NavigationView {
            List{
                ForEach(searchText == "" ? pokemon : pokemon.filter({
                    $0.name.contains(searchText.lowercased())
                })) { entry in
                    HStack {
                        Circle() //Pokemon Image  
                        NavigationLink("\(entry.name)".capitalized, destination: Text("Detail view for \(entry.name)"))
                    }
                }
            }
            .onAppear {
                PokemonManager().getData() { pokemon in self.pokemon = pokemon
                    
                    for pokemon in pokemon {
                        print(pokemon.name)
                    }
                }
            }
            .searchable(text: $searchText)
            .navigationTitle("PokePass")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

PokemonAPI:

import Foundation

struct CurrentPokemon: Codable {
    var results: [Pokemon]
}

struct Pokemon: Codable, Identifiable {
    var id = UUID()
    var name: String
    var url: String
}


class PokemonManager {
    func getData(completion: @escaping ([Pokemon]) -> ()) {
        guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon?limit=151") else {
            return
        }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            guard let data = data else { return }
            
            let pokemonList = try! JSONDecoder().decode(CurrentPokemon.self, from: data)
            
                DispatchQueue.main.async {
                    completion(pokemonList.results)
                }
        }
        .resume()
    }
}

Upvotes: 3

Views: 5030

Answers (1)

Use let id = UUID() in Pokemon, this will avoid decoding it, and that is what you want, since id is not part of the data.

You can also use this approach:

struct Pokemon: Codable, Identifiable {
    var id = UUID()
    var name: String
    var url: String
    
    enum CodingKeys: String, CodingKey {
        case name, url
    }
}

EDIT-1

and use @State var pokemon = [Pokemon]() in ContentView

Upvotes: 2

Related Questions