如何以 Swift 串接 TDX 的公車、臺鐵、高鐵,捷運 API

運輸資料流通服務平臺(TDX)提供了豐富的 API,方便我們存取公車,捷運,高鐵,台鐵等各類交通資訊。接下來讓我們以高鐵時刻表為例,示範如何以 Swift 串接 API。

連到 TDX 網站

註冊帳號

串接 TDX API 必須搭配 API key,因此請先點選右上的註冊,有了 TDX 帳號才能取得 API key。

點選申請註冊

彼得潘只是一個平凡的作家,因此只能選擇一般會員的申請註冊。

輸入帳號資訊

信箱驗證

請從信箱收信,點選驗證網址。

等待帳號審核通過

帳號審核需要最多三個工作日的時間。可以先出去玩,三天後再開始寫程式。

別太擔心,只要你沒做虧心事,相信都能收到下圖的審核通過通知。彼得潘經過 3 小時就收到通知了。

登入 TDX

取得 API key — Client Id & Client Secret

TDX 的 API key 由 Client Id & Client Secret 組成。登入成功後,點選資料服務 > API 金鑰,然後點選下圖紅色框框的編輯。

複製下圖的 Client Id & Client Secret

取得 access token

為了串接 TDX API,我們必須在 http header 裡包含 access token。access token 是一串特別的字串,而且它就像世界所有好吃的食物一樣,是會過期的。

TDX 在開發文件詳細說明了 token 的使用方式。彼得潘比較喜歡方法 2,將 token 存在 App 裡。當發送 API 失敗,發現 token 過期時,再重新取得 token。

取得 token 的 curl 指令如下。

curl --request POST \
--url 'https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=YOUR_CLIENT_ID \
--data client_secret=YOUR_CLIENT_SECRET \

以下 Swift 程式可產生對應的 request,請將 clientId & clientSecret 換成自己的 clientId & clientSecret。

let url = URL(string: "https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token")!
var request = URLRequest(url: url)
request.httpMethod = "post"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
let clientId = "1234"
let clientSecret = "12345678"
let data = "grant_type=client_credentials&client_id=\(clientId)&client_secret=\(clientSecret)".data(using: .utf8)
request.httpBody = data

回傳的 JSON 可依以下文件的說明解析,串接 API 需要的 token 就在 access_token。

查看 API 文件

由於彼得潘時常往返台北高雄,接下來就讓我們試試抓取高鐵資訊吧。

先從 TDX 的首頁點選開發指引 > API 說明

選擇基礎服務下的公共運輸-軌道 V2

點選 THSR 高鐵。

點選取得當天所有車次的時刻表資料。

下圖為當天所有車次時刻表的 API 說明,從中可了解 API 的網址和參數,網址結尾是 v2/Rail/THSR/DailyTimetable/Today,參數 $format=JSON 可讓回傳的資料變 JSON 格式。

點選 Execute 測試 API 和研究回傳的 JSON 資料。

回傳的 JSON 結果如下。

串接今天高鐵所有車次時刻表 API

依據剛剛的 API 文件,以及下圖呼叫 TDX API 服務的說明,可了解 API 的網址和 http header 如何設定。記得要在 http header 設定 authorizationBearer ACCESS_TOKEN,否則串接 API 時會出現錯誤,後台會回傳 no Authorization header found

以下 Swift 程式可產生對應的 request,請將 accessToken 換成自己的 access token。

let url = URL(string: "https://tdx.transportdata.tw/api/basic/v2/Rail/THSR/DailyTimetable/Today?$format=JSON")!
var request = URLRequest(url: url)
let accessToken = "123456"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "authorization")

使用 URLSession 發送 request 成功後,取得的 JSON 如下。

現在剩下的任務變成利用 JSONDecoder 解析 JSON 資料,有興趣的讀者可再參考以下連結。

串接其它 API

學會抓取高鐵車站資料後,串接其它 API 也是一樣的原理,比方以下文章介紹公車資訊的相關 API。

--

--

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

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com