#15 利用 Airtable 開發 iOS App
Published in
8 min readMay 21, 2024
這次作業我打算藉著先前地圖猜謎app延伸來完成。
這個app將從 Airtable 獲取數據,並在 UITableView 中顯示地圖名稱和圖片。其中使用 URLSession 進行網絡請求,還涵蓋了使用第三方庫Kingfisher 讀取網路圖片。
步驟 1:設置 Airtable 資料庫
首先,在 Airtable 中創建了一個資料庫(base),並添加了所需的表格和字段。在這個例子中,我們有一個名為 mapInfo
的表格,包含以下字段:
areaName
:區域名稱areaInfo
:區域資訊(例如介紹連結)areaImage
:區域圖像(附件類型)
步驟 2:定義資料結構
定義與 Airtable 資料結構對應的 Swift 結構。創建一個名為 Struct.swift
的文件:
import Foundation
struct MapInfo: Codable {
let records: [Record]
}
struct Record: Codable {
let id, createdTime: String
let fields: Fields
}
struct Fields: Codable {
let areaImage: [AreaImage]
let areaInfo: String
let areaName: String
}
struct AreaImage: Codable {
let id: String
let width, height: Int
let url: String
let filename: String
步驟 3:實現 Airtable API 串接
我們需要從 Airtable 獲取數據,並將其解碼為 MapInfo
結構。創建一個名為 NetworkManager.swift
的文件:
import Foundation
let apiKey = APIKey.default
var mapInfoData: MapInfo?
func fetchData(completion: @escaping (MapInfo?) -> Void) {
if let url = URL(string: "https://api.airtable.com/v0/app1MfmI8sP5PmaSp/mapInfo") {
var request = URLRequest(url: url)
// 設置授權標頭
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
// 發送 HTTP 請求
URLSession.shared.dataTask(with: request) { data, response, error in
if let data {
// 列印 JSON 資料
let decoder = JSONDecoder()
do {
// 將 JSON 資料解碼成 MapInfo 結構
let result = try decoder.decode(MapInfo.self, from: data)
mapInfoData = result // 將解碼結果存入全域變數
completion(result) // 調用完成閉包
} catch {
print(error)
completion(nil) // 如果解碼失敗,傳回 nil
}
} else if let error {
print(error)
completion(nil) // 如果請求失敗,傳回 nil
}
}.resume()
}
}
步驟 4:設置 TableView
接下來,我們需要設置 UITableView
來顯示從 Airtable 獲取的數據。創建一個名為 MapInfoTableViewController.swift
的文件:
import UIKit
import Kingfisher
class MapInfoTableViewController: UITableViewController {
var mapInfoData: MapInfo?
override func viewDidLoad() {
super.viewDidLoad()
fetchData { data in
DispatchQueue.main.async {
if let data = data {
// 使用 data 做其他處理
self.mapInfoData = data
self.tableView.reloadData() // 重新加載表格視圖
} else {
// 處理數據加載失敗的情況
let alert = UIAlertController(title: "Error", message: "Failed to load data", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mapInfoData?.records.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MapInfoTableViewCell", for: indexPath) as! MapInfoTableViewCell
if let record = mapInfoData?.records[indexPath.row] {
cell.mapName.text = record.fields.areaName
cell.url = record.fields.areaInfo
if let url = record.fields.areaImage.first?.url {
cell.mapImage.kf.setImage(with: URL(string: url))
}
}
return cell
}
}
步驟 5:設置 TableView Cell
創建一個名為 MapInfoTableViewCell.swift
的文件:
import UIKit
import SafariServices
class MapInfoTableViewCell: UITableViewCell, SFSafariViewControllerDelegate {
@IBOutlet weak var mapName: UILabel!
@IBOutlet weak var mapImage: UIImageView!
var url: String?
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func openUrl() {
guard let urlString = url, let url = URL(string: urlString) else { return }
let safariVC = SFSafariViewController(url: url)
safariVC.delegate = self
UIViewController().present(safariVC, animated: true, completion: nil)
}
}
結語
通過這次作業,我學習到串接 Airtable api 獲取地圖資訊並在 TableView 中顯示,並利用 Kingfisher 庫讀取網路圖片。此外,我還設置了 TableView 的 Delegate 和 DataSource,實現了數據的顯示和管理,接下來我想嘗試把api中的連結做成按鈕,並顯示在safari上。