Swift JSON教學:如何利用 Data Taipei 公開資料庫建立 App

隨著開發資料的潮流,目前有越來越多的政府資料、組織資料可供社會大眾以及開發者利用。究竟要如何從開放資料的接收,轉換成可以在 App 中呈現的樣貌,今天我們將透過一份台北市動物園的資料為例,帶大家一起實際撰寫一個簡單的 Swift App!


首先,我們打開瀏覽器,輸入 data.taipei 進入新版的台北市政府資料開放平台,然後我們搜尋”動物園”。

data-taipei

在搜尋結果中,找到台北市立動物園_動物資料

data-taipei-zoo

進入之後,在使用資料的下拉選單中,點選 API 進入。

data-taipei-api

此時,我們會得到兩個網址,這次的練習要使用的就是第二個網址。

  1. 資料集的說明 – http://data.taipei/opendata/datalist/apiAccess?scope=datasetMetadataSearch&q=id:5cb73231-b741-48b3-bec3-2ef57bb10029
  2. 台北市立動物園_動物資料 – http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=a3e2b221-75e0-45c1-8f97-75acbd43d613

data-taipei-api-access

點擊第二個網址進入後,發現他的資料是JSON格式。

若無法看到階層式架構的樣貌,請安裝對應的瀏覽器外掛,以Chrome為例,可安裝JSONView

data-taipei-zoo-json

這個時候,我們已經確認找到我們要的資料,接著來分析資料的結構。最外層對應 Swift 是 Dictionary,裡面只有一筆資料,Key 值為 result:

而從result再進去,對應的也是一個Dictionary,裡面有四筆資料:

而這四筆資料分別是:

  • offset – 每次回傳時的位移筆數。例如offset=5,就代表跳過前面5比,從第6筆資料開始回傳。
  • limit - 每次回傳資料筆數的上限
  • count – 資料集的筆數
  • sort – 排序方式

所有動物資料被置放在 results 這個 Key 所對應的內容,我們趕快來看看吧:

  • A_Name_Ch – 中文名
  • A_Summary – 摘要說明
  • A_Keywords – 關鍵字
  • A_AlsoKnown – 別名
  • A_Geo – WGS84座標系統(WKT格式)
  • A_Location – 館區
  • A_POIGroup – POI群組
  • A_Name_En – 英文名
  • A_Name_Latin – 學名
  • A_Phylum – 分類學_門
  • A_Class – 分類學_綱
  • A_Order – 分類學_目d
  • A_Family – 分類學_科
  • A_Conservation – 保育等級
  • A_Distribution – 地理分布
  • A_Habitat – 棲地型態
  • A_Feature – 形態特徵
  • A_Behavior – 生態習性
  • A_Diet – 食性
  • A_Crisis – 面臨問題
  • A_Interpretation – 解說
  • A_Theme_Name – 主題網頁
  • A_Theme_URL – 主題網頁URL
  • A_Adopt – 動物認養焦點物種
  • A_Code – 編號代號
  • A_Pic01_ALT ~ A_Pic04_ALT – 照片說明(4組)
  • A_Pic01_URL ~ A_PIc04_URL – 照片URL(4組)
  • A_pdf01_ALT ~ A_pdf02_ALT – PDF說明(2組)
  • A_pdf02_URL ~ A_pdf02_URL – PDF URL(2組)
  • A_Vioce01_ALT ~ A_Voice03_ALT – 聲音說明(3組)
  • A_Vioce01_URL ~ A_Voice03_URL – 聲音URL(3組)
  • A_Vedio_URL – 影片URL
  • A_Update – 資料更新日期
  • A_CID – 序號

真是太棒了!一個動物就有這麼多的資料可以利用,究竟要怎麼把這些資料放進APP中呢?讓我們趕快來試試看吧!

建立簡單的動物 App

首先,建立一個新的 Xcode 專案,使用Master-Detail樣板。

master-detail-xcode-template

專案名稱命名為HelloZoo,組織名稱、識別符自訂,選擇Swift程式語言,適用於各種裝置,其他選項目前不勾選。

hellozoo-project-option

找個地方儲存專案後,進入MasterViewController.swift,增加一個dataArray來儲存取得的所有動物資料。

並在viewDidLoad中開始使用NSURLSession讀取data.taipei的資料。

之後,將MasterViewController設定遵循NSURLSessionDelegateNSURLSessionDownloadDelegate兩個協定:

跟著我們實作完成下載的方法。其中我們使用 NSJSONSerialization.JSONObjectWithData 方法進行 JSON 資料處理,再依據先前觀察的結構,取得result對應中的results所對應的陣列。最後,重新整理Table View。

編者按:do-try-catch 是 Swift 2 新加入的關鍵字,用來作錯誤處理。如想瞭解更多有關Swift 2 的錯誤處理模式,請參考較早前編寫的Swift 2 初學者指南

我們已整理好JSON 資料。要將動物資料呈現在Table View,我們只要實作以下的方法。

此時執行看看,Xcode 會在 Console區告訴你:

編者按:App傳輸安全(App Transport Security,簡稱ATS)是iOS9的新特性。這個功能的目的是透過一些最佳配置的強化來改善App與網頁服務間的連線安全。其中一項是安全連線的使用。有了ATS,所有的網路要求要透過HTTPS來傳送。倘若你使用HTTP來做網路連結,ATS會封鎖需求並顯示錯誤。要解決這個問題,你應該透過HTTPS去帶HTTP來載入一個網路請求,這是Apple的要求。不過,倘若你要對應的網站不是你所能控制的,而無法符合ATS需求,其中一種可能的解決方案就是退出App傳輸安全。要這麼做的話,你需要在你的App的Info.plist加上一個key來關掉ATS。

一般的HTTP網址被視為不安全,若真的還是希望能存取,我們要到Info.plist中做這個設定,請在Info.plist檔案按下右鍵,Open As -> Source Code。最後面加上:

這個時候再執行看看,就可以看見動物資料了!

hellozoo-demo-1

呈現動物圖片

那要如何在第二頁中呈現圖片呢?

由於我們並不確定台北市立動物園是不是有為每一種動物準備圖片,所以我們必須要判斷:

  • 如果有圖片 -> 在該項目點擊後,在第二頁中顯示動物圖片
  • 如果沒有圖片 -> 在該項目點擊後,在第二頁中顯示預設圖片

首先,請先準備一張預設圖片,在本例子中,我們準備的是AppCoda的Logo圖檔。下載完成後,可修改檔名為appcoda.png

接著,請將appcoda.png加到Assets.xcassets。在Storyboard中的第二個畫面(Detail)中,增加一個ImageView在中間,設定預設圖片為appcoda.png,並且把原本樣板中的 label 往上移動。你可以利用 Add Missing Constraints功能要求 Xcode 自動設定 layout constraints。

adding-image-view

此時也請將 ImageView 拉線至 DetailViewController.swift,並建立Outlet關係,名稱為imageView。

connecting-outlet

佈局好畫面之後,由於每一隻動物的資料是一個Dictionary,所以我們需要在第二個畫面的控制器中建立一個變數,來儲存這隻動物的各項屬性:

DetailViewController.swift中,請增加一個變數(thisAnimalDic),加上剛剛拉過來的imageView以及原本的detailDescriptionLabel,此時程式碼如下:

在第一個畫面中,拿到資料時,我們已將資料儲存在dataArray陣列,所以我們可在MasterViewControllerprepareForSegue方法中,依據使用者目前所選取的項目,去陣列中拿到那一隻動物的資料,然後傳遞至下一個畫面:

在第二個畫面控制器 (DetailViewController.swift) 中,當我們拿到資料後,圖片只是一個網址,必須透過相同的方式,向伺服器取得圖片資料。首先請一樣設定遵循這兩個協定: NSURLSessionDelegateNSURLSessionDownloadDelegate

接著,我們試著取得網址,並利用Swift語言的if let語法來處理:

  • 如果有圖片 -> 取得該圖片資料
  • 如果沒圖片 -> 不動作 (因為已經在Storyboard中設定了預設圖片了)

請將viewDidLoad更新至以下程式碼:

我們利用NSURLSessiondownloadTaskWithURL方法下載指定的動物圖片。接著實作協定中的方法,將取得的資料交給imageView來呈現:

恭喜你完成了!趕快來測試看看。如果該動物有圖片,你會看到以下畫面:

hellozoo-demo-final

是不是覺得意猶未盡?試試看,你能不能自己增加以下的部分:

  • 修改第二個畫面的標題為該動物的名稱
  • 修改第二個畫面的描述為該動物的摘要說明(並注意顯示的大小)

供你參考,請從 GitHub 下載本文的完整 Xcode 專案。如你對這篇教學有任何意見,歡迎留言討論。


行動開發學院創辦人,現職為資策會課程研發經理,擔任「行動開發」課程總監,專長於iOS APP開發、HTML5 Web開發,並於中央大學資管系、元智大學資工系等多所學校授課,致力推廣APP開發教育。與我聯繫:[email protected]。網站:www.mobiledev.tw

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This