A simple Pokedex app written in Swift that implements the PokeAPI, using Combine and data driven UI.

Overview

icon

SwiftPokedex

SwiftPokedex is a simple Pokedex app written by Viktor Gidlöf in Swift that implements the PokeAPI. For full documentation and implementation of PokeAPI have a look at the their documentation.

This sample app demonstrates:

  • RIB architecture 🏛
  • Network capabilities using Combine ⚡️
  • Data driven table and collection views 💾
  • Async image download and caching 🏞
  • Swift dot syntax ✏️
  • Custom navigation bar 🧭
  • Custom fonts 📖
  • Infinite scrolling 📜

It downloads an array of Pokemon and displays them in a grid. The most dominant color of the Pokemon sprite is detected and shown in the UI. It also shows a list of the most common items.

pokdex1 pokedex2

Architecture 🏛

SwiftPokedex is written in my own interpretation of the RIB archtitecure created by Uber. The name RIBs is short for Router, Interactor and Builder, which are core components of the architecture.

Builder 🛠

The builder build the views with all of their dependencies.

final class PokedexViewBuilder {
    
    static func build() -> NavigationController {
        let router = PokedexRouter()
        let interactor = PokedexInteractor(router: router)
        let viewController = PokedexViewController(interactor: interactor)
        let navigationController = NavigationController(rootViewController: viewController)
        
        router.navigationController = navigationController
        return navigationController
    }
}

Interactor 👇🏻

The interactor is the link between the user input and the view and includes all the interations the user can make. It also contains a router object. So when the user interacts with the view we call the interactor to make the appropriate interaction.

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    collectionView.deselectItem(at: indexPath, animated: true)

    interactor.selectPokemon(at: indexPath, in: collectionView)
}

Router 🕹

The router is in charge of navigation. And since routers are decoupled from view controllers we can easily navigate to anywhere in the app.

func routeToDetailView(pokemon: PokemonDetails, color: UIColor) {
    let detailView = DetailViewBuilder.build(from: pokemon, withColor: color)
    navigationController?.pushViewController(detailView, animated: true)
}

Networking ⚡️

SwiftPokedex uses Combine for all the API calls to the PokeAPI. This small structure is all that's needed to make any type of request to the API. The PokemonAPI and ItemAPI is then build around this network agent. It supports requesting pokemons and items at the moment.

struct NetworkAgent {
    func execute<T: Decodable>(_ request: URLRequest, logJSON: Bool = false) -> AnyPublisher<T, Error> {
        URLSession.shared.dataTaskPublisher(for: request)
            .tryMap {
                if logJSON { print($0.data.prettyJSON ?? "no json") }
                return $0.data
            }
            .decode(type: T.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }
}

Data driven tables and collection views 💾

The table views and collection views are data driven and they setup their own UI based on the data they are given. So setting up a collection view data source is done like this:

let items = pokemon.map { CollectionCellConfiguration<PokedexCell, PokemonDetails>(data: $0) }
let section = UICollectionView.Section(items: items)
let collectionData = UICollectionView.DataSource(sections: [section])

By configuring the cells using CollectionCellConfiguration we tell the collection view that the data type we want to use is PokemonDetails and the custom cell is PokedexCell. This make setting up cells type safe as well. Then the collection view automatically renders that data with those cells. No need to implement any of the collection delegate or data source methods in the view controller. That is done with the CollectionCellConfigurator protocol and a subclass of UICollectionViewController.

Todo 📝

The PokeAPI is very extensive and it contains a lot of things. Here are some things that I plan to implement further down the line:

  • Request pokemon
  • Search pokemon
  • Pokedex pagination
  • Show pokemon details
  • Request items
  • Search items
  • Show item descriptions
  • Implement other parts of the API such as:
    • Moves
    • Abilities
    • Berries

Requirements ❗️

  • Xcode 12.0+
  • iOS 14.1+
  • Swift 5+
You might also like...
A utility that reminds your iPhone app's users to review the app written in pure Swift.
A utility that reminds your iPhone app's users to review the app written in pure Swift.

SwiftRater SwiftRater is a class that you can drop into any iPhone app that will help remind your users to review your app on the App Store/in your ap

swift-highlight a pure-Swift data structure library designed for server applications that need to store a lot of styled text

swift-highlight is a pure-Swift data structure library designed for server applications that need to store a lot of styled text. The Highlight module is memory-efficient and uses slab allocations and small-string optimizations to pack large amounts of styled text into a small amount of memory, while still supporting efficient traversal through the Sequence protocol.

Functional data types and functions for any project

Swiftx Swiftx is a Swift library containing functional abstractions and extensions to the Swift Standard Library. Swiftx is a smaller and simpler way

Measure the power output from a car or any moving vehicle from GPS data and weight
Measure the power output from a car or any moving vehicle from GPS data and weight

GPSDyno Measure the power output from a car or any moving vehicle from weight and GPS data of your iOS device. This is just a example project and shou

Easier sharing of structured data between iOS applications and share extensions
Easier sharing of structured data between iOS applications and share extensions

XExtensionItem XExtensionItem is a tiny library allowing for easier sharing of structured data between iOS applications and share extensions. It is ta

Taking a string containing a csv file and split it into records (aka lines) containing fields of data (aka Array of SubStrings)

Swift .csv parser Taking a string containing a csv file and split it into records (aka lines) containing fields of data (aka Array of SubStrings). Par

Project shows how to unit test asynchronous API calls in Swift using Mocking without using any 3rd party software

UnitTestingNetworkCalls-Swift Project shows how to unit test asynchronous API ca

A tiny generator of random data for swift

SwiftRandom SwiftRandom is a tiny help suite for generating random data such as Random human stuff like: names, gender, titles, tags, conversations Ra

Framework for easily parsing your JSON data directly to Swift object.
Framework for easily parsing your JSON data directly to Swift object.

Server sends the all JSON data in black and white format i.e. its all strings & we make hard efforts to typecast them into their respective datatypes

Comments
Releases(v1.1)
Owner
Viktor G
Senior iOS Software Engineer 💻 📲
Viktor G
Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data.

Pigeon ?? Introduction Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data. It is heavily inspired by React Qu

Fernando Martín Ortiz 369 Dec 30, 2022
AnalyticsKit for Swift is designed to combine various analytical services into one simple tool.

?? AnalyticsKit AnalyticsKit for Swift is designed to combine various analytical services into one simple tool. To send information about a custom eve

Broniboy 6 Jan 14, 2022
🌤 Swift Combine extensions for asynchronous CloudKit record processing

Swift Combine extensions for asynchronous CloudKit record processing. Designed for simplicity.

Chris Araman 46 Dec 8, 2022
Handy Combine extensions on NSObject, including Set.

Storable Description If you're using Combine, you've probably encountered the following code more than a few times. class Object: NSObject { var c

hcrane 23 Dec 13, 2022
Use this package in order to ease up working with Combine URLSession.

Use this package in order to ease up working with Combine URLSession. We support working with Codable for all main HTTP methods GET, POST, PUT and DELETE. We also support MultipartUpload

Daniel Mandea 1 Jan 6, 2022
RandomKit is a Swift framework that makes random data generation simple and easy.

RandomKit is a Swift framework that makes random data generation simple and easy. Build Status Installation Compatibility Swift Package Manager CocoaP

Nikolai Vazquez 1.5k Dec 29, 2022
Simple and Lightweight App Version Tracking for iOS written in Swift

AEAppVersion Simple and lightweight iOS App Version Tracking written in Swift I made this for personal use, but feel free to use it or contribute. For

Marko Tadić 12 Nov 11, 2022
A simple, but efficient CSV Parser, written in Swift.

CSV CSV.swift is a powerful swift library for parsing CSV files that supports reading as [String], [String: String] and Decodable, without sacrificing

Ben Koska 4 Nov 28, 2022
Simple getter for bundle informations, written in Swift

BundleInfos Simple getter for bundle informations It's simple and static way for getting information from main bundle Requirements iOS 8.0+ Xcode 7.3

Jay Choi 1 Dec 3, 2017
TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app.

TypeStyle TypeStyle is a handy app for iPhone and iPad that generates text using different styles and decorations. It is a native Swift iOS app. Featu

Eugene Belinski 31 Dec 14, 2022