33 訂可不可飲料app-前篇
Published in
8 min readAug 18, 2023
目前的我不會爬蟲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.
}
下集待續~
(這次真的很難,感謝各位幫助我的大大們)