我把 2021 年寫的 Vision App 拿出來,開始用 AI 一步步重構它
Pose Coach 是我在 2021 年開始開發的 iOS / Vision 專案。2026 年重新打開它時,我開始用 AI 補 spec、拆 plan、加測試,並一步步把它重構成更完整的分析工具。
這系列想記錄一件我最近做得滿有感的事:
我把一個 2021 年開始寫的 iOS 專案重新拿出來,然後開始用 AI 一步一步重構它。
這個專案叫 Pose Coach。
一開始它其實不是什麼很完整的產品,比較像是我想試試看 Apple Vision framework 可以做到什麼程度。當時的核心想法很單純:做一個影片播放器,然後在播放影片的時候做人像辨識,把骨架 overlay 疊在畫面上。
換句話說,它的起點就是:
- 匯入影片
- 播放影片
- 用 Vision framework 做 body pose detection
- 把辨識結果畫在播放器上
以 2021 年的時間點來說,這已經是滿有趣的實驗了。
但問題也很明顯。
那時候沒有現在這種 AI coding workflow。遇到功能想法,大多就是自己打開 Xcode,邊想邊寫。架構不一定一開始就拆得很好,文件通常也不會先補齊,測試更常常是「先手動跑看看」。
專案可以動,但久了之後就會變成一種狀態:
「我大概知道它在幹嘛,但要改之前要先重新想一下。」
2026 年重新打開它
到了 2026 年,我又重新開始整理 Pose Coach。
這次不太一樣的是,我手上已經有 AI 可以用了。
一開始我也很自然地想說,那是不是可以直接叫 AI 幫我加功能?
例如:
幫我加一個螢幕分享功能。
或是:
幫我在影片分析裡面加球棒軌跡。
聽起來很合理,但是這種要求其實太大了。
專案開發不像一個單純的 script。它會牽涉到:
- Xcode project 設定
- SwiftUI / UIKit 的生命週期
- AVFoundation 的 sample buffer
- Vision framework 的座標系
- 相機與相簿權限
- Simulator 跟真機差異
- 非同步 pipeline
- UI 狀態與 thread safety
我相信隨著 AI 的進步,可能不遠的未來我們就不需要考慮這些了
但在當下,AI 這些還是會寫出「看起來合理」的 code,但軟體開發的麻煩通常不是看起來合理就可以。
可以 build 嗎?
真機可以跑嗎?
權限有補嗎?
座標有沒有上下顛倒?
慢動作影片的時間軸有沒有算錯?
這些問題都不是一句「幫我實作」就能處理乾淨的。
所以後來我慢慢把流程調整成另一種方式:
先讓 AI 幫我讀懂舊專案,再把想法整理成 spec,接著拆成 implementation plan,最後才開始小步實作與驗證。
不是重寫,而是慢慢重構
重新整理舊專案時,很容易冒出一個念頭:
不然整個重寫好了。
隨著 AI 進步,或許完全重寫這件事已經不再如以往那麼遙不可及,
但現階段我比較偏好先重新認識這個已經存在的專案,一步一步重構它。
我的理由是 AI 寫的很快,但人理解的速度肯定跟不上 AI 產出的速度。
至少在 2026 的今天,我還是覺得作為一名軟體開發人員應該要理解要交付出去的產品。
因此我先列出了已經存在的功能:
- 影片匯入
- 播放器
- Vision body pose detection
- skeleton overlay
- 多語系
- CoreData 儲存影片資訊
- 一些已經驗證過的 UI 流程
每次只處理一個明確問題:
- 播放器太散,就先收斂播放器架構
- Body detection UI 不好操作,就先寫 spec 重設互動
- 想把畫面分享到第二台裝置,就先定義 MVP
- JPEG / H.264 串流路線不好維護,就再往 WebRTC 重構
- 想做球棒軌跡,就先把幾何計算拆成純函式
- 想算速度,就先補 frameIndex 與 metrics 計算
這種方式比較慢,但比較不會失控。
而 AI 在這裡最有幫助的地方,不是「一次幫我寫完整個功能」,而是幫我把每一步變小、變清楚、可以驗證。
第一個大整理:播放器
近一年 commit 裡,第一個明顯的大重構是播放器。
當時做了幾件事:
- 重構 player architecture
- 修正 pose overlay alignment
- 收斂成單一 player
- 加入 pinch zoom / pan
- 支援 portrait orientation
- 把截圖、frame step、pose analysis、clip export 拆成 feature
過去想法驗證時欠下的技術債,現在有機會還了 XD
過多的依賴,職責混亂的 function 開始進行拆分
例如播放器不同的功能放倒 Modules/Player/Features 這種比較明確的位置,讓播放器真的只是播放器。
這也是我後來用 AI 重構時很常做的一件事:
先讓邊界變清楚。
一個功能如果講不清楚它屬於哪裡,AI 通常也很難改得乾淨。
從「直接做」變成「先寫 Spec」
到了 body detection UI redesign 和 screen sharing 的時候,我開始比較明確地使用 spec / plan。
以前可能會直接說:
幫我改一下 body detection UI。
但這種 prompt 對 AI 來說太模糊了。
什麼叫「改一下」?
是改 UI layout?
是改狀態模型?
是改 overlay?
還是改使用流程?
所以我開始先寫 spec,把事情講清楚:
- 現在的問題是什麼
- 目標是什麼
- 這次要包含什麼
- 這次不包含什麼
- 架構怎麼切
- UI 怎麼動
- 錯誤怎麼處理
- 要怎麼測
這件事看起來像是在寫文件,但實際上比較像是在限制 AI 的發揮空間。
AI 不是不能發揮,而是不能亂發揮。
尤其是在舊專案裡,很多東西都已經有歷史包袱。你沒有先講清楚邊界,它很可能會「順手」幫你改一堆不該改的地方。
螢幕分享是第一次大型功能實驗
Pose Coach 原本是單機使用。
但如果真的拿來做運動分析,只在手機上看其實不太夠。有時候會希望第二台裝置可以同步看到畫面,例如教練看一台、使用者拿一台。
所以我開始做螢幕分享。
一開始的 MVP 很保守:
- 同一個 Wi-Fi
- 一對一連線
- 廣播端把相機畫面加上骨架 overlay 傳出去
- 接收端全螢幕顯示
- 支援基本錄製與回溯剪輯
同時也明確寫了不做什麼:
- 不做多台接收
- 不做自動重連
- 不一開始就做 WebRTC
- 不把所有進階 overlay 都塞進 MVP
這個「不做什麼」非常重要。
因為如果沒有邊界,AI 很容易把 MVP 做成一個看起來很完整但其實很難驗證的大怪物。
後來這條線也真的走了好幾次重構:從 JPEG / MCSession,到 H.264 delayed playback,再到 WebRTC。中間有很多 thread safety、播放延遲、真機權限、連線狀態的問題。
這些東西都不是 AI 單靠想像能一次寫對的。
但有 spec 和 plan 之後,至少每次出問題時,我知道目前是在修哪一層。
從人像辨識走到球棒軌跡
另一條有趣的線是 Swing Arc。
Pose Coach 原本主要是做人像辨識,但最初就是我想分析自己的揮棒與投球
有先去做了一個 Python 版本,使用 YOLO 模型,在限定條件下看起來不錯
但是當要實作在 iOS 上還是得一步一步處理
- YOLO 模型導入
- 從偵測框推估球棒尖端
tipFromBbox - 用 pivot / tip 畫出球棒形狀
batPolygon - 用
SwingArcState管理軌跡 - 加入 EMA 平滑
- 加入 warmup
- 加入 jump filter
- 加入 speed threshold
- 用 FIFO 控制 history 長度
這段我覺得很適合交給 AI 協助,但前提是要先拆成純函式和小狀態機。
像 tipFromBbox、batPolygon 這種幾何計算,如果直接藏在 Vision pipeline 裡,很難測,也很難知道 AI 寫錯哪裡。
但如果先拆成純函式,就可以先寫測試。
能先變成純函式的邏輯,就先抽出來測。
AI 寫 UI 或 pipeline 可能會受很多環境影響,但寫純函式時,只要測試夠清楚,就比較容易控制品質。
不只畫線,還要算速度
畫出球棒軌跡之後,下一個自然問題就是:
那速度呢?
這時候事情又變有趣了。
如果只是一般影片,可以用 frame 間距估速度。但慢動作影片會有時間軸問題。CMSampleBuffer 的 PTS 可能是放慢後的播放時間,不一定等於真實捕捉時間。
所以後來我在 spec 裡明確寫下:
速度計算要用 frameIndex + nominalFrameRate。
也就是:
real_dt = frameDelta / nominalFrameRate
這樣 120fps 或 240fps 慢動作影片才不會被低估速度。
這個例子讓我更確定一件事:
AI 可以幫忙寫 code,但關鍵技術決策還是要先被講清楚。
如果 spec 沒有寫出 nominalFrameRate 這個決策,AI 很可能會直接用 PTS 算,然後得到一個看起來合理但物理意義錯誤的答案。
這系列會寫什麼
接下來這個系列,我想用 Pose Coach 當主線,記錄這幾個重構階段:
- 重新打開 2021 年的 Pose Coach
- 先把播放器救回來,重構成單一 Player + Feature 架構
- 用 Spec 重寫 Body Detection UI
- 讓第二台裝置也能看:螢幕分享 MVP
- 從 JPEG / H.264 重構到 WebRTC
- 從人像辨識到球棒軌跡:Swing Arc 的 TDD 開發
- 不只畫線,還要算速度:Swing Metrics 怎麼補上
- 回頭看:AI 對重構舊 iOS 專案最有幫助的地方
我不打算把它寫成 AI 工具教學。
比較想寫成一個真實的開發紀錄:
- 哪些地方 AI 真的省了很多時間
- 哪些地方 AI 很容易寫錯
- 為什麼舊專案不能一口氣重寫
- spec 和 plan 怎麼幫我控制重構範圍
- TDD 怎麼讓 AI 產出的 code 比較可驗證
- 專案哪些地方還是一定要靠工程師判斷
目前的感覺
如果要用一句話總結這段時間的感覺,我會說:
AI 沒有讓重構變得不需要思考。
它只是讓我可以把很多原本很花時間的步驟加速:
- 幫我讀 code
- 幫我整理 spec
- 幫我拆 plan
- 幫我補測試
- 幫我做小步重構
- 幫我檢查邊界情境
但方向要自己定。
哪些東西該保留,哪些東西該重構,哪些地方要先測,哪些問題必須上真機驗證,這些還是軟體開發人員自己的責任。
所以這系列比較像是一份紀錄:
一個舊 iOS 專案,在 AI 出現之後,可以怎麼被重新整理。
不是魔法,也不是重寫。
就是一步一步,把原本有點鬆散的東西,慢慢整理成更能繼續長大的樣子。