期末作業-Step4

本篇說明如何下載訂單資訊並表列在Table視圖,前置步驟請參考下方連結

新增訂單視圖與佈局,需設置NavigationController與TabBarController

新增對應視圖的控制器OrderTableViewController.swift與客製化OrderTableViewCell.swift

全局配置

接著要設置解碼訂單格式的物件,由於需要利用到Airtable自動產生的建檔日期,所以下載的訂單物件跟上傳的訂單物件屬性配置會不同

//  Order.swift
// OrderDrink-API
import Foundation

// 下載用
struct OrderResource: Decodable {
let records: [OrderObject]
}

struct OrderObject: Decodable {
let createdTime: Date
let fields: OrderField
}

接著到OrderTableViewCell.swift拉好IBOutlet,與完成相應的約束條件

完成前置作業後,即可開始撰寫表格視圖控制器,首先先建立空清單用來存放下載的訂單資料,注意物件型別是剛剛新增的OrderObject,並於viewDidLoad與按下refresh時呼叫fetchOrderData抓取Airtable訂單資料。


import UIKit

class OrderTableViewController: UITableViewController {

var orderItemes = [OrderObject]()

override func viewDidLoad() {
super.viewDidLoad()

self.navigationItem.leftBarButtonItem = self.editButtonItem

fetchOrderData()
}

@IBAction func refresh(_ sender: UIBarButtonItem) {

fetchOrderData()
}

fetchOrderData程式碼如下,注意由於要解碼Airtable的日期格式,所以先要呼叫DateFormatter()來設定格式,並套用decoder.dateDecodingStrategy屬性,才能於解碼時將日期格式正確轉換到Date型別。


func fetchOrderData() {

let api = "patWEGAks"

if let url = URL(string: "https://api.airtable.com/v0/appFh/Order") {

var request = URLRequest(url: url)
request.setValue("Bearer \(api)", forHTTPHeaderField: "Authorization")

URLSession.shared.dataTask(with: request) { data, response, error in

if let data,
let response = response as? HTTPURLResponse,
response.statusCode == 200,
error == nil {
// 驗證資料抓取
let content = String(data: data, encoding: .utf8)
print(content!)

let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
do {
let orderData = try decoder.decode(OrderResource.self, from: data)
self.orderItemes = orderData.records

DispatchQueue.main.async {
self.tableView.reloadData()
}

} catch {
print(error)
}

} else {
print(error ?? "download error")
}

}.resume()
}
}

JSON日期格式解碼轉換請參考peter的文章

最後是處理DataSource資料,一樣要把Date型別的屬性透過格式設定轉成字串存進cell.dateLabel.text


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return orderItemes.count
}


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

// Configure the cell...
let orderItem = orderItemes[indexPath.row].fields

cell.userLabel.text = "訂購人:" + orderItem.username
cell.drinkLabel.text = "飲品名:" + orderItem.drink
cell.iceLabel.text = "冰量:" + orderItem.ice
cell.sizeLabel.text = "容量:" + orderItem.size
cell.sugarLabel.text = "甜度:" + orderItem.sugar
cell.priceLabel.text = "金額:" + (orderItem.price?.description ?? "")
cell.memoLabel.text = "備註:" + (orderItem.memo ?? "")

let orderDate = orderItemes[indexPath.row].createdTime
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd HH:mm"
cell.dateLabel.text = "訂購時間:" + dateFormatter.string(from: orderDate)

return cell
}

大功告成

好不容易完成期末作業,真的難度與複雜度很高,感謝Peter的扎實的課程指導,與豐富的文章庫讓我能夠逐步處理問題,總算是了結的一大障礙,可喜可賀,可喜可賀。後續會再針對細節與功能進行優化。

--

--