Created
February 5, 2021 17:41
-
-
Save nicnocquee/170c29786cc6cfc669c6767a77a92d34 to your computer and use it in GitHub Desktop.
sample of fetching list of pokemon using swift combine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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