📲iPlayground 開源 App 背景故事

今年 iPlayground,我自告奮勇接下了 iOS app 的開發。開發背後的一些小故事,我覺得可以拿出來分享,就寫了這篇文章。

今年 iPlayground,我自告奮勇接下了 iOS app 的開發(按這裡下載)。開發背後的一些小故事,我覺得可以拿出來分享,就寫了這篇文章。

接手理由

參加 try! Swift Tokyo 時,發現它們的 app 做得不錯,而且有開源。在第一天活動時,遇到 app 有個使用者體驗上的困擾,但應該不難修。想說我如果能修好,可以去發個 PR。

結果等想到時上去一看,已經有人發了 PR 搞定了。這就是一個熱衷開發的社群會有的樣貌,真的很貫徹開源精神,我覺得超棒

另一方面,try! Swift Tokyo 的 app 使用 SwiftUI 與 TCA,跟我熟悉的框架一模一樣。於是產生了一個念頭:如果我來寫 iPlayground 的 app,也許有機會在國際 iOS 社群之間做個比較、互相學習

再者,雖然我錄製過多集的 iOS 開發配飯吃 • SwiftUI + TCA 系列,也寫過一些 TCA 相關文章,但是從來沒有一個比較複雜的開源 app 作為範例。這會是個很實際的 sample project。

規劃與資料準備

一個研討會的 app 會有哪些功能,不難想像。主要就是顯示議程、講者、工作人員、贊助商、場地資料,以及重要連結等等。

iPlayground 的官網已經使用一個開源 repo 放一些 JSON 檔,所以 app 只需要沿用即可。

不過我想說,既然是 JSON,如果多人協作時不小心改壞就不好了。就用 Claude Code 寫出一個 Swift Package,用 Codable 確保資料欄位,並且寫一些測試來確保格式與欄位正確。

這些 GitHub Actions 的 CI 工作流程,都可以在這裡看到。比較有趣的是,這邊用的是 Ubuntu 的 runner 來跑測試,而不需要 Mac。算是利用了一下 Swift 跨平台的特性。

注入現在時間,進行時空跳轉

上述的部分,我有在開發時直播與錄影(作為宣傳活動的手段)展示,都在這個 iOS 開發配飯吃 iPlayground 2025 App 開發特別篇播放清單

後面的部分,因為時間的因素,就沒有錄影了。以下我用文字補充。

有一個比較特別的巧思:app 主要是在研討會期間使用,只要對照時間表,可以得知顯示當前的活動進展。所以我們在議程列表放置了一個目前、下一個、下下一個活動內容的小區塊。而且可以按下去,直接跳轉到列表。

像這樣的功能,一定得測試。最好是能在 SwiftUI Preview 就可以直接操作不同時間點的效果。

我使用了 Point-Free 的 Swift Dependencies 來注入「現在」。透過修改 @Dependency(\.date.now) 讀出的時間,就可以做時空跳轉。

這是我覺得非常重要的技巧。相關程式碼可以從這裡開始看起。

場地資訊用上了台灣街景

另一個有用到的好玩技術,是 Apple MapKit 的 Look Around。

Google Maps 的街景功能,在 Apple Maps 叫做 Look Around(環視)。2023 年 9 月底,Apple Maps 在台灣有完整的環視功能,所以開發者可以免費拿來用。效果很好、實作起來也很簡單。

展開的效果,請看我推文上的錄影

實作的程式碼,則是在這邊。我為了要讓它符合 Swift Concurrency,所以在載入時先在 Task.detached,再切回 Task { @MainActor in。如果你知道更好的方法,可以跟我分享。

使用到的 AI 工具

這次我用得比較多的 AI 工具反而是 Cursor,因為 SwiftUI 我還是自己寫,然後用 Cursor 的自動完成來加速。這個過程還是跟以前一樣舒服。

至於 Claude Code,主要是用來幫忙完善 TCA 的測試覆蓋。

另外,這次 iPlayground 使用了跟在 try! Swift Tokyo 一樣的 Flitto 翻譯服務,所以我有稍微參考一下如何實作,但看起來他們的 app 只是將 SDK 的 sample code 稍作修改 。

那樣當然是可以用。但為了好玩,我花了一點時間用 Claude Code 把 sample code 的 view model 改成 TCA 的 reducer

主要卡住的點在於,Flitto SDK 是 xcframework。所以,我自己把 header 翻出,貼給 Claude Code 去參考,不然它會一直瞎猜 property name。其他的部分就很順利了。

行動提示

延伸閱讀