Pokémon Weakness for iOS这是一款展示了宠物小精灵Pokémon弱点的app,用Swift写成。
Requirements
- iOS 9.0+
- Xcode 7.0+
项目结构图
architecture.png
Libraries used in this project
现代开发需要高度异步,开发工具所提供的异步编程功能是否强大、方便而又令人愉悦?
PromiseKit是一款贴心的iOS异步开发类库,更同时支持Objective-C和Swift的promises完整实现。
PromiseKit 是一个比较简单的函数化集成第三方库,让 oc 或者 swift 能够更容易的实现函数化编程。这点和 Rx 或者 RAC有着更好的代码复杂度。
1.png 260 X 240 pixels
1_small.png 124 X 114 pixels
Domain.Model
Pokemon.swift
import Foundation
// 口袋妖怪
struct Pokemon {
let name: String // 名称
let number: Int // 编号
let color: Int // 颜色
let weaknesses: [String] // 弱点
}
PokemonType.swift
import UIKit
/**
List of pokemon's types extracted from http://pokemondb.net/type
*/
enum PokemonType: String {
case Normal // 1.正常
case Fire // 2.火
case Water // 3.水
case Electric // 4.电
case Grass // 5.草
case Ice // 6.冰
case Fighting // 7.战斗
case Poison // 8.毒药
case Ground // 9.地面
case Flying // 10.飞行
case Psychic // 11.通灵的
case Bug // 12.臭虫
case Rock // 13.岩石
case Ghost // 14.鬼
case Dragon // 15.龙
case Dark // 16.黑暗
case Steel // 17.钢
case Fairy // 18.仙女
}
extension PokemonType {
var color: UIColor {
switch self {
case Normal:
return UIColor(hex: 0x4a4a4a)
case Fire:
return UIColor(hex: 0xff5722)
case Water:
return UIColor(hex: 0x2196f3)
case Electric:
return UIColor(hex: 0xffc107)
case Grass:
return UIColor(hex: 0x4caf50)
case Ice:
return UIColor(hex: 0x81d4fa)
case Fighting:
return UIColor(hex: 0xf44336)
case Poison:
return UIColor(hex: 0x21d0a9)
case Ground:
return UIColor(hex: 0x795548)
case Flying:
return UIColor(hex: 0x2962ff)
case Psychic:
return UIColor(hex: 0x9c27b0)
case Bug:
return UIColor(hex: 0x009688)
case Rock:
return UIColor(hex: 0x9e9e9e)
case Ghost:
return UIColor(hex: 0xe2e2e2)
case Dragon:
return UIColor(hex: 0x5c6bc0)
case Dark:
return UIColor(hex: 0x263238)
case Steel:
return UIColor(hex: 0x607d8b)
case Fairy:
return UIColor(hex: 0xe91e63)
}
}
}
Domain.Repository
PokemonDataSource.swift
import PromiseKit
protocol PokemonDataSourceProvider {
func dataSource() -> PokemonDataSource
}
protocol PokemonDataSource {
func getPokemons() -> Promise<[Pokemon]>
}
PokemonRepository.swift
import PromiseKit
protocol PokemonRepository {
func getPokemons() -> Promise<[Pokemon]>
}
DefaultPokemonRepository.swift
import Foundation
import PromiseKit
struct DefaultPokemonRepository: PokemonRepository {
private let getPokemonDataSourceProvider: PokemonDataSourceProvider
init(getPokemonDataSourceProvider: PokemonDataSourceProvider) {
self.getPokemonDataSourceProvider = getPokemonDataSourceProvider
}
func getPokemons() -> Promise<[Pokemon]> {
return getPokemonDataSourceProvider.dataSource().getPokemons()
}
}
PokemonDiskModelParser.swift
import Foundation
private struct JSONKeys {
static let name = "name"
static let number = "number"
static let color = "color"
static let weaknesses = "weaknesses"
}
struct PokemonDiskModelParser: Parseable {
func parse(element: [String: AnyObject]) -> Pokemon {
let name = element[JSONKeys.name] as! String
let number = element[JSONKeys.number] as! Int
let color = element[JSONKeys.color] as! Int
let weaknesses = element[JSONKeys.weaknesses] as! [String]
return Pokemon(
name: name,
number: number,
color: color,
weaknesses: weaknesses
)
}
}
GetPokemonsFromDiskDataSource.swift
import Foundation
import PromiseKit
private struct PokemonListFixture {
static let path = "pokemon_list"
}
struct GetPokemonsFromDiskDataSource: PokemonDataSource {
private let pokemonDiskModelParser: PokemonDiskModelParser
init(pokemonDiskModelParser: PokemonDiskModelParser) {
self.pokemonDiskModelParser = pokemonDiskModelParser
}
func getPokemons() -> Promise<[Pokemon]> {
return firstly { _ -> Promise<[[String: AnyObject]]> in
return JSONLoader.fixturePromise(
PokemonListFixture.path
)
}.then { json -> [Pokemon] in
return self.pokemonDiskModelParser.parseArray(json)
}
}
}
Domain.UseCase
GetPokemonsUseCase.swift
import Foundation
import PromiseKit
class GetPokemonsUseCase {
private let pokemonRepository: PokemonRepository
init(pokemonRepository: PokemonRepository) {
self.pokemonRepository = pokemonRepository
}
func getPokemons() -> Promise<[Pokemon]> {
return pokemonRepository.getPokemons()
}
}