33 訂可不可飲料app-前篇

目前的我不會爬蟲www所以手殘黨用手key…其實17種飲料也很快啦…

不要小看文組生的打字速度阿….

目前畫面內容:

首先註冊Airtable建立後台以便串接資料。

建立好資料後,我們要建立api的網址以及取的token,我們可以到postman這邊先測試是否可以抓到資料。

ok~看起來是成功找到資料了,這邊抓資料的部份我卡非常久,主要是因為我的struct沒有跟著json的資料走,然後層級也搞不太清楚。

struct結構(這邊你可以請chat gpt幫忙,但細節要修,比如url的型別):

import Foundation

struct DrinksBody: Codable {
let records: [Record]

struct Record: Codable {
let id: String
let createdTime: String
let fields: Fields
}

struct Fields: Codable {
let content: String
let name: String
let lPrice: Int?
let mPrice: Int
let image: [Image]

struct Image: Codable {
let id: String
let width: Int
let height: Int
let url: URL
let filename: String
let size: Int
let type: String
let thumbnails: Thumbnails

struct Thumbnails: Codable {
let small: ThumbnailInfo
let large: ThumbnailInfo
let full: ThumbnailInfo

struct ThumbnailInfo: Codable {
let url: URL
let width: Int
let height: Int
}
}
}
}
}

我們先創建一個容器來裝json抓到的東西。

var items = [DrinksBody.Record]()

class drinksTableViewController: UITableViewController {
var items = [DrinksBody.Record]()

...

並建立一個解碼的function,在viewdidload的時候就跑他。

class drinksTableViewController: UITableViewController {
var items = [DrinksBody.Record]()

override func viewDidLoad() {
super.viewDidLoad()
fetchNames()

}
 //JSON解碼的程式,把資料存在array裡面;並顯示資料在表格上。
func fetchNames(){
// 設定 API 的 URL
let url = URL(string: "https://api.airtable.com/v0/app41W2DAKMjqdKlY/kebuke")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
// 設定 API 請求標頭,包含驗證授權
request.setValue("Bearer patrEo7XWMphchYMy.90deeb0c42ef0ce98c1d116f2c92b00ec4802e97d3219e4b6dd379fb6cd2471d", forHTTPHeaderField: "Authorization")
// 發送 API 請求
URLSession.shared.dataTask(with: request) { data, response, error in
print("Error API: \(String(describing: error))")
if let data,
let content = String(data: data, encoding: .utf8) {
// 解碼 JSON 格式的資料
let decoder = JSONDecoder()
do {
let kebuke = try decoder.decode(DrinksBody.self, from: data)
// 將取得的飲料資料存入 items 陣列
self.items = kebuke.records
// 在主執行緒更新表格
DispatchQueue.main.async {
self.tableView.reloadData()
}

} catch {
print("Error decoding JSON: \(error)")
}
}
// 開始 API 請求
}.resume()
}

接下來創建tableViewCell,並拉好outlet。

// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

//數量為names的count
return items.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "\(drinksTableViewCell.self)", for: indexPath) as! drinksTableViewCell

// Configure the cell...

let item = items[indexPath.row]
cell.drinkName.text = item.fields.name
cell.drinkImage.kf.setImage(with: item.fields.image.first?.url)
return cell
}

我們點選每一個飲料會進入detail的說明頁面。這邊飲料清單頁面拉IBSegueAction把前頁的資料傳到後面去。

 @IBSegueAction func showDetail(_ coder: NSCoder) -> detailViewController? {
let controller = detailViewController(coder: coder)
if let row = tableView.indexPathForSelectedRow?.row {
controller?.item = items[row]
}
return controller
}

細節頁面我們要有個var item: DrinksBody.Record?

這樣才能接前面傳來的資料。

import UIKit
import Kingfisher

class detailViewController: UIViewController {
var item: DrinksBody.Record?

@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var contentLabel: UILabel!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var shadowView: UIView!

override func viewDidLoad() {
super.viewDidLoad()
nameLabel.text = item?.fields.name
contentLabel.text = item?.fields.content
imageView.kf.setImage(with: item?.fields.image.first?.url)

// Do any additional setup after loading the view.
}

下集待續~

(這次真的很難,感謝各位幫助我的大大們)

--

--

HydeeChen
彼得潘的 Swift iOS / Flutter App 開發教室

純種文組生轉職程式異世界 持續學習swift, Objective C, flutter…