寶可夢圖鑑App

目的:練習TableView、網路抓取API、解析JSON、透過IBSegueAction傳資料

API來源:https://pokeapi.co/

1.觀察API建立struct(總共用了兩個API及一個JSON檔,完整程式碼放在GitHub)

import Foundation

struct Pokemon : Codable {
let results : [Results]
}
struct Results : Codable {
let name : String
let url : String
}
import Foundation
struct PokemonDetail : Codable {
let name : String
let id : Int
let sprites : Sprites
let stats : [Stats]
let types : [Types]
}
struct Sprites : Codable {
let other : Other
}
struct Other : Codable {
let officialArtwork : OfficialArtwork
enum CodingKeys: String, CodingKey {
case officialArtwork = "official-artwork"
}
}
struct OfficialArtwork : Codable {
let frontDefault : String
enum CodingKeys: String, CodingKey {
case frontDefault = "front_default"
}
}
struct Stats : Codable {
let baseStat : Int
let stat : Stat
enum CodingKeys: String, CodingKey {
case baseStat = "base_stat"
case stat
}
}
struct Stat : Codable {
let name : String
}
struct Types : Codable {
let type : Type
}
struct Type : Codable {
let name : String
}

2.抓取API以及解析JSON

var pokemon = [Results]()
var pokemonImages = [Images]()

override func viewDidLoad() {
super.viewDidLoad()
fetchData()
fetchImage()
}

//抓取本地資料並解析
func fetchImage() {
do { //generated為json檔名
if let bundlePath = Bundle.main.path(forResource: "generated",ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
let decodedData = try JSONDecoder().decode(PokemonImage.self,from: jsonData)
self.pokemonImages = decodedData.image
}
} catch {
print(error)
}
}
//抓取網路上的API
func fetchData() {
let urlString = "https://pokeapi.co/api/v2/pokemon/?limit=905"
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url) { data, response, error in
let decoder = JSONDecoder()
if let data {
do {
let pokemondata = try decoder.decode(Pokemon.self,from: data)
self.pokemon = pokemondata.results
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
} else {
print(error!)
}
}.resume()
}
}

3.建立TableView資料

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pokemon.count
}
//使用自定義的Cell 這裡要新增一個UITableViewCell的檔案並在裡面拉Outlet
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "\(PokemonCell.self)", for: indexPath) as! PokemonCell
cell.pokemonName.text = pokemon[indexPath.row].name
let url = URL(string: pokemonImages[indexPath.row].url)
cell.pokemonImage.kf.setImage(with:url) //使用Kingfisher套件

return cell
}

4.透過IBSegueAction傳資料,把第一個API裡的url object傳到ViewController,

ViewController這邊則要先宣告好存放資料的位置(detailUrl)

@IBSegueAction func showDetail(_ coder: NSCoder) -> ViewController? {
let controller = ViewController(coder: coder)
controller?.detailUrl = pokemon[tableView.indexPathForSelectedRow!.row].url
return controller
}

5.ViewController在解析一次前一頁傳過來的API,剩下的部份就剩設計了

var detailUrl = String()
let urlString = detailUrl
//以下省略

Demo:

GitHub:

--

--