🥇SwiftUI 讀完就入坑 #9 SwiftUI + TCA 專案的模組化最佳實踐
累積多個中大型專案的 SwiftUI + TCA 模組化實戰經驗,三年半精華濃縮在這篇。是我目前寫過最有系統的一次整理,值得深入瞭解。
5/8 更新:我把模組化專案的模版開源在此,歡迎使用 https://github.com/ethanhuang13/SwiftUI-TCA-Template
前言
切模組可以說是一門藝術,也是考驗程式碼架構與分類功力的絕佳方式。
今天要分享的模組化拆分法,是根據十來個專案,包括公司的 3 個中大型 SwiftUI + TCA 專案,累積三年半實務經驗,研究出的 SwiftUI + TCA 模組化最佳實踐的核心精神。
對於有在使用 TCA 或是想入坑 TCA 的朋友,應該會增加不少功力。
這篇文章相當進階,最好是對 TCA 有一定使用經驗再來讀。
我學習切模組的基礎是來自於 Point-Free 的 Modularization: Part 1(這集免費)、Modularization: Part 2,以及 Point-Free 的 TCA 示範專案──開源遊戲 App isowords。
後來實際操作下去以後,覺得踩到了一些坑,所以逐漸發展成自己的解決方案。
建議配菜
我在 iOS 開發配飯吃 #0 有教過把整個 iOS App 的程式碼,都放進 Local Swift Package 的作法。
一個好處是可以繞開 Xcode 專案檔容易衝突的問題,不過在 Xcode 16 用 Folder 就可以避開。
更重要的好處是,用 Package manifest 更容易定義用到的外部依賴,以及模組的切分。
這些模組拆分方法都是基於上面提到的 Local Swift Package。雖然你也可以在 Xcode 開 framework target 來切,但是我還是覺得放在 Package 比較管理。
所以如果你還不熟悉用 Local Swift Package 來搭配 Xcode 專案,可以看一下 iOS 開發配飯吃 #0。
目標
我切模組的目標是:
- 每個模組的職責非常明確(這是基本),讓分工合作的團隊成員都知道要怎麼分類與管理程式碼。獨立開發者的話,就把未來的自己當成團隊成員
- TCA reducers 作為 App 的核心商業邏輯,能夠快速地執行 TCA reducers 的測試是至關重要的。要是編譯速度太慢,會讓人不想好好寫測試,TDD 也不可能實現
- 確實掌控 reducers 的測試覆蓋率。測試覆蓋率可以用模組為單位來觀察,所以切到剛剛好有需要測試的範圍為一個模組,這個覆蓋率就很有參考價值
- 可以順利跑起 SwiftUI Previews,達到接近即時更新的效果。之前的文章談過很多次,我很強調能夠看到 SwiftUI Previews 才能做好狀態設計。正確地切模組可以讓 Previews 每次更新只編譯需要編譯的部分,這樣就可以更快看到更新
- 只有在跑整個 App 的時候才需要編譯外部依賴,進一步增進開發效率
- 當有錯誤的時候,可以依照依賴的順序來編譯不同模組,逐步排除問題。這一點在現今的 Xcode 專案與 Swift 編譯器的表現下,會比想像中來得重要
模組化架構圖
來看一張簡化版本的圖。