---
# System prepended metadata

title: '技術-iOS #9-新世代的 UI 架構 SwiftUI 初體驗，用 WebView 整合多彩多姿的網頁資源'
tags: [新人資訊]

---

---
tags: 新人資訊
GA: G-YWCCFEGXSJ
---
[新人資訊](https://hackmd.io/@newman/portal-info)

# 技術-iOS #9-新世代的 UI 架構 SwiftUI 初體驗，用 WebView 整合多彩多姿的網頁資源

Storyboard 從 iOS 5 就有了，SwiftUI 是 iOS 13 之後才有的，找到寫得很好的比較文：https://medium.com/technology-nineleaps/swift-ui-or-storyboard-675ff2b40829 ，同樣寫 iOS 當然要學新版的技術，尤其是對剛入門的新手，沒有舊作品需要維護的包袱，更應該沒有懸念的擁抱新架構，先來試試從無到有寫出一個簡單的一頁式 App。

新增專案中注意在 Interface 選項中選擇 SwiftUI

![](https://newprediction.blob.core.windows.net/notebook-img/pPydqHm.png)

SwiftUI 令人激賞之處就是預覽畫面和程式碼完全雙向同步，加入 UI 元件可以拉到畫面，也可以拉到程式碼中，對既有 UI 元件做屬性修改也是可以自由選擇用拖拉或直接寫程式碼，非常方便。

![](https://newprediction.blob.core.windows.net/notebook-img/w4btgZp.png)

畫面區塊可以減下做成一個自製元件重複使用，如以下就是因為顯示電話和 email 兩種資訊的方式很相似，就做成一個共用元件。

![](https://newprediction.blob.core.windows.net/notebook-img/rizh0Cc.png)

再把之前的專案用 SwiftUI 復刻感受其差異性。

![](https://newprediction.blob.core.windows.net/notebook-img/byS9AFJ.png)

![](https://newprediction.blob.core.windows.net/notebook-img/sDM9T6X.png)

接下來再做一次綜合練習，用 List 元件盛裝一系列的文章列表，點擊顯示另一明細頁，在明細頁裝一個 browser 顯示原始網頁的效果。文章列表來自於此網頁：https://news.ycombinator.com/ ，他們還提供了非常友善的 api：https://hn.algolia.com/api。以下把呼叫 api 解析 json 等工作包裝在一個 class NetworkManager，這段的重點在於實作 ObservableObject，開放一個可訂閱的欄位以裝飾詞 @Published 標示之，呼叫 api 的過程各段步驟都要等待也可能發生錯誤，所以用了一堆 if let，確保資料正確再繼續向下處理；另外因為要開放 UI 元件訂閱，所以要將回傳值的變動事件用 DispatchQueue 放到主執行緒依序執行。

![](https://newprediction.blob.core.windows.net/notebook-img/oimf7f8.png)

以上為了解析 json 格式，還需要觀察 api 回傳規格，照樣建立合用的容器 struct 如下：

![](https://newprediction.blob.core.windows.net/notebook-img/2YGWXWo.png)

UI 部分則擔任觀察者角色，一旦 networkManager.posts 有異動就會驅動 UI 元件 List 的內容重新生成，如此觀察者和被觀察者均設定完成，還需最後關鍵動作，點燃導火線以驅動連鎖反應，就是在 View 的 onAppear 事件中執行 fetchData()。

![](https://newprediction.blob.core.windows.net/notebook-img/VBAiE2q.png)

以上 List 中重複出現的部分為文章的 points and title，外層包了一個 NavigationLink，目的地為 DetailView，且帶一個 url 為參數，其內又包了一層 WebView，分層負責使每段程式碼都不長：

![](https://newprediction.blob.core.windows.net/notebook-img/mLZtqb5.png)

![](https://newprediction.blob.core.windows.net/notebook-img/ZRduzPJ.png)

顯示網頁是一個複雜的工作，所幸 WebKit 程式庫已經完成所有工作，只要引入即可，實作 UIViewRepresentable 的兩個 func 寫法都相當簡單，簡單幾行就完成所有工作真是幸福感破錶，最後執行效果如下：

https://youtu.be/aZG_pYtXbi8

By Newman Chen 2022/8/11

