Skip to content

Instantly share code, notes, and snippets.

@nicnocquee
Created February 5, 2021 17:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicnocquee/170c29786cc6cfc669c6767a77a92d34 to your computer and use it in GitHub Desktop.
Save nicnocquee/170c29786cc6cfc669c6767a77a92d34 to your computer and use it in GitHub Desktop.
sample of fetching list of pokemon using swift combine
import UIKit
import Combine
struct PokemonResponse: Codable{
let results: [Pokemon]
}
struct Pokemon: Codable{
let name: String
let url: String
}
struct PokemonDetailResponse: Codable{
let id: Int
let name: String
let height: Int
let weight: Int
let types: [Types]
}
struct Types: Codable{
let slot: Int
let type: Type
}
struct Type: Codable{
let name: String
}
/// Fetch a pokemon from URL
/// - Parameter urlString: URL of the pokemon
/// - Returns: A publisher with output PokemonDetailResponse
func getPokemon (_ urlString: String) -> AnyPublisher<PokemonDetailResponse, Error> {
let url = URL(string: urlString)!
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: PokemonDetailResponse.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
/// Fetch a list of pokemon without details
/// - Parameter urlString: URL of the list of pokemon
/// - Returns: A publisher with output PokemonResponse
func getPokemonList (urlString: String) -> AnyPublisher<PokemonResponse, Error> {
let url = URL(string: urlString)!
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: PokemonResponse.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
/// Fetch a list of pokemon with details
/// - Returns: A publisher with output an array of PokemonDetailResponse
func getPokemonListWithDetails () -> AnyPublisher<[PokemonDetailResponse], Error> {
return getPokemonList(urlString: "https://pokeapi.co/api/v2/pokemon/")
.map(\.results)
.flatMap {
Publishers
.MergeMany($0.map { getPokemon($0.url) })
.collect()
.eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
let cancellable = getPokemonListWithDetails().sink { (completion) in
print("done")
} receiveValue: { (pokemons) in
print(pokemons.map({ "- \($0.name): \($0.types.first?.type.name ?? "")" }).joined(separator: "\n"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment