今天要來聊聊 SwiftUI。最近很多人在問,尤其是一些剛入門或想從其他領域轉過來的朋友。SwiftUI 到底好在哪?為什麼 Apple 要推這個?
老實說,這不是一個三言兩語能講完的問題。它不只是一個新工具,更像是 Apple 對未來 App 開發方式的一種宣告。它背後有一整套思維模式的轉變。
重點一句話
簡單講,SwiftUI 的核心精神就是「用更少的程式碼,做更多的事」,而且是專為蘋果自家生態系量身打造的。如果你打定主意只在 Apple 的世界裡玩,那它幾乎是現階段最優雅、也最有效率的選擇。但...對,人生就是有這個 but,這也意味著你被「綁」在這個生態裡了。
它到底解決了什麼問題?
在有 SwiftUI 之前,我們大多用的是 UIKit(或 AppKit for macOS)。也不是說 UIKit 不好,它很強大、很穩定,畢竟撐了這麼多年。但它就是...很「傳統」。你需要手動管理很多狀態、畫面跟資料的同步,程式碼寫起來很囉唆。
我自己的感覺啦,以前用 UIKit 開發,大概有三分之一的時間都在處理這些 UI 跟資料怎麼對上的問題。一個按鈕按下去,資料改了,然後我要記得去更新畫面上三個地方的標籤。少做一步,畫面就跟資料對不上了。很煩。
SwiftUI 用的「宣告式 UI」就想解決這個。你不用再跟系統說「第一步做這個、第二步做那個」,而是直接跟它說:「嘿,我希望畫面『長得像』這個資料。」 當資料一變,畫面就自動更新。沒了,就這樣。開發者可以把更多精力放在 App 的核心邏輯上,而不是在 UI 的細節裡打滾。
還有一個關鍵,就是 SwiftUI 是用 Struct(結構體)去建構畫面的。這點超級重要,但常常被忽略。
簡單科普一下,在 Swift 裡,Struct 是存在 Stack(堆疊)這種記憶體區域的,它的管理方式很單純,就是先進後出,速度飛快。而傳統 UI 元件常用的 Class(類別)是存在 Heap(堆積)裡,管理起來比較複雜,需要做記憶體計數(ARC),效能開銷比較大。你可以想像成 Stack 是一疊盤子,拿取跟放回都很快;Heap 則像一個大倉庫,東西亂放,每次存取都要先查一下清單,慢很多。
所以 SwiftUI 畫面上的所有東西,本質上都是這些輕巧、快速的 Struct。這讓它在渲染、更新時的效能非常好。這不是說它跑起來一定比優化過的 UIKit 快十倍,而是在開發的過程中,你就已經站在一個比較高的效能起跑點上了。
那...跟其他框架比起來呢?
這大概是最多人問的。我直接做個表,可能會清楚一點。這是我自己的觀察啦,不一定完全精準,但大概是這個感覺。
| 比較項目 | SwiftUI | UIKit (傳統原生) | React Native / Flutter (跨平台) |
|---|---|---|---|
| 開發效率 | 非常高。程式碼少,預覽快。真的,那個即時預覽省下的編譯時間太可怕了。 | 普通。程式碼比較繁瑣,很多東西要手動處理。需要一直 build & run。 | 也蠻高的。特別是 Hot Reload 功能,改完馬上看得到。但有時候會遇到一些奇怪的 bug... |
| 執行效能 | 原生頂尖。Struct-based UI 天生就有優勢,跟系統結合得最好。 | 也是原生頂尖。畢竟是老大哥,優化到極致的話,效能絕對沒話說。 | 通常不錯,但永遠隔了一層。特別是動畫或複雜操作,有時會感覺到那個「橋接」的延遲。 |
| 跨平台能力 | 蘋果生態系限定。一支程式碼通吃 iPhone, iPad, Mac, Watch, TV。但想上 Android?門都沒有。 | 僅限蘋果平台,而且不同裝置(iOS/macOS)還要寫不同的 code。 | 最大賣點。一套 code 跑 iOS 跟 Android,理論上是這樣啦。實際上還是要處理很多平台差異。 |
| UI 一致性 | 自動適應。同一個元件在不同裝置上會自動長成該有的樣子,很省心。 | 需要大量手動調整。你要自己去判斷現在是在 iPad 還是 iPhone 上,然後給不同的佈局。 | 可以做到像素級一致。但缺點就是,你的 App 在 iPhone 上可能看起來像 Android App,反之亦然。少了點「原生味」。 |
| 生態與未來性 | 蘋果的親兒子,未來絕對是主流。所有新功能、新硬體都會優先支援。 | 還會存在很久,但明顯不是未來方向了。很多舊專案還是得靠它維護。 | 社群驅動。優點是資源多,缺點是不穩定,某個套件作者不爽不幹了,你就頭大了。 |
| 學習曲線 | 概念新,但API少。上手算快,但要精通「狀態管理」那套思維需要時間。 | API 龐大又複雜。要學的東西非常多,對新手不太友善。 | 看你從哪來。如果你是 Web 開發者,React Native 會很親切。但要搞懂原生底層的東西還是很花時間。 |
說到這個,原文有提到一個觀點我覺得蠻有趣的。他說在 App Store 上,蘋果開發者的收入平均比 Android 開發者高。這點 Apple 官方也常常拿出來講,根據他們的新聞稿,到 2023 年為止,開發者在 App Store 生態系中已經創造了超過 1.1 兆美元的營收。當然,這是全球數據,而且大部分錢還是進了頭部開發商的口袋。
不過呢,這也反映出一個現象:蘋果用戶的付費意願普遍比較高。這點在台灣的開發者社群(像是 iT 邦幫忙或 Dcard 上的討論)也常常被提到。所以如果你想做的是付費 App 或是有 App 內購買的服務,專心耕耘蘋果生態系,可能真的是一條投資報酬率比較高的路。
好用的開發工具們
光有 SwiftUI 還不夠,真正讓整個開發體驗起飛的,是它跟 Xcode 這套開發工具的整合。有幾個功能真的是用了就回不去了。
即時預覽 (Previews)
這個前面提過了,但真的要再強調一次。你寫 UI 程式碼的同時,旁邊的視窗就直接顯示出畫面。你可以同時開好幾個預覽,一個看 iPhone 正常模式、一個看 iPhone 夜間模式、一個看 iPad、一個看字體放大後的無障礙模式。修改程式碼,所有預覽「同時」更新。這省下的時間跟精力太可觀了。
除錯大師:Debug Memory Graph & Instruments
App 寫久了,最怕的就是記憶體問題。像是「記憶體洩漏 (Memory Leak)」,就是東西用完了卻沒有被好好釋放,一直佔著空間,App 跑久了就越來越慢,最後閃退。
Xcode 內建了一堆超強的工具來抓這些問題。
- Debug Memory Graph:這東西超酷。它可以直接畫出一張圖,告訴你現在記憶體裡有哪些物件,誰跟誰有關係。如果出現「循環引用」(例如 A 抓著 B,B 又抓著 A,兩個都放不掉),在這張圖上一目了然。
- Instruments - Leaks:這個更直接,它就是專門用來抓 Memory Leak 的。一跑下去,哪裡有漏,它直接幫你標出來。
- Instruments - Allocations:這個工具可以鉅細靡遺地告訴你,你的 App 在什麼時候、因為什麼操作,佔用了多少記憶體。如果你發現某個功能一開,記憶體就狂飆,用這個去跑一次,大概就能抓到兇手。
我自己是覺得,這些工具才是 Apple 生態系真正的護城河。它不只給你釣竿(SwiftUI),還給你聲納探測器(除錯工具),讓你清楚知道水底下發生了什麼事。
常見的誤解與掙扎
雖然 SwiftUI 很香,但它也不是銀彈。很多剛接觸的人會有一些...嗯...錯誤的期待。
誤解一:「SwiftUI 什麼都能做,UIKit 可以淘汰了。」
錯。大錯特錯。雖然 SwiftUI 進步很快,但還是有很多底層、複雜的功能是它暫時做不到或做起來很麻煩的。例如一些很刁鑽的相機控制、地圖底層 API 的操作等等。這時候,你還是得回頭去用 UIKit 來實現那部分的特定功能,然後再把它包裝起來給 SwiftUI 用。所以,現實情況是「混用」,而不是「取代」。把 SwiftUI 當成主要的 UI 框架,但手邊還是要準備好隨時能拿出 UIKit 來解決特定問題。
誤解二:「宣告式 UI 就是簡單,不用管生命週期了。」
這只對了一半。你確實不用再像以前一樣管 `viewDidLoad`, `viewDidAppear` 這些瑣碎的視圖生命週期。但是,你變成要管理「資料的生命週期」。你的資料什麼時候被創建、什麼時候被銷毀、它的作用域在哪裡...這些問題變得超級重要。在 SwiftUI 裡,你對 `@State`, `@Binding`, `@StateObject`, `@ObservedObject` 這些「屬性包裝器」的理解深度,直接決定了你的 App 會不會出現一堆奇奇怪怪的 bug。
掙扎點:「我想做個超炫的客製化 UI,但 SwiftUI 好難改!」
沒錯。這其實是 Apple 故意的。SwiftUI 的設計哲學是鼓勵你「遵循平台規範」,而不是「天馬行空」。它希望你做的 App 看起來就像一個「原生 App」。所以,它提供的元件在一定程度上是「防呆」的,讓你很難把它改成奇形怪狀。如果你真的需要高度客製化的視覺效果,要嘛你得用很深的功力去組合、客製化,要嘛...UIKit 或是其他遊戲引擎可能更適合你。
總結來說,我自己是覺得,選擇 SwiftUI 就是選擇了一整個生態系。你得到的不是一個單純的 UI 框架,而是一套從開發、預覽、除錯、測試到發佈的完整解決方案。它的限制也很明顯,就是你會被牢牢鎖在蘋果的院子裡。
但說真的,如果你的目標用戶本來就都在這個院子裡,那在這個環境裡用最順手的工具,專心把產品做好,好像也是個很合理的選擇。
聊聊你的看法:
如果你是獨立開發者,或是要開啟一個新專案,你會選擇用 SwiftUI 專攻 Apple 平台,還是會選 React Native / Flutter 這類跨平台框架去接觸更廣的用戶?在下面留言分享你的考量吧!
