這份文件描述 CameraHuman 目前建議的開發流程。重點不是理論上的最佳實務,而是這個 repo 目前真的需要怎麼做,才能避免反覆踩同樣的坑。
這份流程主要處理四件事:
- 改功能時不要再把 UI、session、設定流弄亂
- 分清楚 code regression 跟本機 Xcode 環境問題
- 把真機驗證重點固定下來
- 讓 git 狀態保持可追蹤
目前這個專案有幾個現實條件:
- 主 app 是
UIKit - 相機與錄影核心依賴
AVFoundation - 主入口是
SceneDelegate + RootTabBarController(自製 dock,不是UITabBar預設外觀) Camera是目前主要功能頁,已拆成CameraSession/CameraRecorder/AudioLevelMonitor三個 service + 多個 custom viewMedia / Chat / Settings已經接進同一個拍攝工作流project.pbxproj採用 Xcode 16 同步資料夾,加新檔到對應子資料夾即自動納入 build,不必手動編輯 pbxproj
每次開發建議照這個順序走。
先明確定義這次改動是以下哪一類:
CameraMediaChatSettingsBuild / wiring
如果是相機功能,先看:
CameraViewController.swift— view + callback wiringCameraSession.swift— capture session、鏡頭、權限CameraRecorder.swift— 錄影狀態機CameraSettingsStore.swiftMediaLibrary.swift
如果是 app 導航或啟動問題,另外看:
先確認 worktree,不要在髒狀態下失去判斷力。
git status --short要看幾件事:
- 有沒有未追蹤的新檔
- 有沒有你這次不打算碰的舊改動
project.pbxproj或Info.plist有沒有被一起改到
如果 worktree 本來就不乾淨,之後回報時要把自己的改動和既有改動分開講。
不要直接進檔案硬改。先理解目前狀態模型。
相機功能至少要先搞清楚:
- 目前 camera position 是什麼
- 有哪些 discovered lens options
- session 在哪裡建立與重建
- 錄影輸出在哪裡開始與結束
- HUD 的數值是即時計算還是寫死
- 比例變更是只影響 UI,還是真的進輸出流程
這一步的目的很直接:避免改到一個按鈕,結果 session、preview、HUD 同時壞掉。
修改時優先遵守這些原則:
- 不要把假的硬體能力呈現在 UI 上
- 不要把
portrait當成鏡頭 - 前鏡頭若沒有多焦段差異,就只顯示單一 front mode
- 後鏡頭鏡頭列表應該由 runtime capability 決定
- 錄影與音訊監看盡量維持在單一 capture workflow 內
如果是 UI 調整,也不要只看視覺;要一起檢查:
- 觸控區域是否合理
- 小螢幕是否擠壓
- 錄影中狀態是否可讀
- 音訊顏色是否仍然符合語意
改完後,先跑固定 build 指令,不要每次換花樣。模擬器 build:
xcodebuild -project CameraHuman.xcodeproj -scheme CameraHuman \
-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' \
-configuration Debug build > /tmp/camerahuman-build.log 2>&1再查 log:
rg -n "error:|warning:" /tmp/camerahuman-build.log看到 build fail 時,不要立刻說功能壞了。先分型。
這類算真正 regression:
- Swift compile error
- unresolved symbol
- type mismatch
- missing file wiring
- duplicated method / property
這類要明確說是本機環境問題,不要誤判成程式錯:
iOS Platform Not Installed(缺對應 SDK)- simulator service / platform runtime 缺失
xcrun simctl找不到指定 device UDID
LaunchScreen.storyboard 之前因為沒在 Info.plist 註冊 UILaunchStoryboardName 會被 letterbox,這個已在當前版本修正。
這個 app 很多功能不能只靠 build。以下是每次相機功能大改後應該實機檢查的項目。
- App 啟動後是否直接進
Camera - 預設前鏡頭 / 後鏡頭是否符合
Settings - 權限未給時 UI 是否仍可理解
- 後鏡頭鏡頭按鈕是否只顯示實際存在的鏡頭
- 前鏡頭是否沒有出現假的多焦段模式
- 切到前鏡頭後,lens UI 是否正確重建
- 預覽畫面是否真的切到對應 input
- 錄影鍵點下去是否立刻切到錄影狀態
REC與 timer 是否有更新- 再點一次是否正常停止
- 錄影完成是否有 toast
- 錄出的檔是否進入
Media
16:9構圖框是否合理4:3構圖框是否合理4:3輸出檔在Media播放時是否比例正確- 前鏡頭
4:3是否有方向或 transform 問題
- 安靜環境下是否接近低值
- 一般說話是否主要落在綠色
- 較大聲時是否進黃色
- 爆音風險時是否進紅色
- 軌道數顯示是否合理
Medialink 一支 clip 後,Chat是否同步顯示- 刪掉 linked clip 後,planner 是否自動清空 link
- 素材註記修改後,列表是否立即刷新
這些是目前專案已經踩過坑的地方,之後不要再退回去。
- 不要把
portrait當 lens - 不要為前鏡頭硬做
0.5x / 1x / 3x - 不要用型號猜測硬體,優先用 runtime discovery
以下這些值要在 main thread 讀:
view.windowwindowSceneinterfaceOrientation
否則很容易再出現 Main Thread Checker。
如果 HUD 顯示某個值:
- 它應該反映真實狀態
- 不應只是裝飾字串
特別是:
LENSREC- 音訊顏色
- 比例標示
每次收尾前至少檢查一次:
git status --short關注點:
- 新檔有沒有漏加
- 是否誤改
project.pbxproj - 是否留下暫時測試碼
- 是否多出不該存在的 debug label / print
如果工作內容很大,建議把 commit 切成:
feature / architectureUI polishdocs
不要把所有邏輯、UI、文件、資源都塞進單一不清楚的 commit。
這個 repo 把文件按用途拆成 7 份,每份只做一件事,避免 drift:
| 檔案 | 用途 |
|---|---|
README.md |
產品 / 架構速覽,給第一次進 repo 的人 |
roadmap.md |
Done + 還沒做的事 + Technical debt(單一來源) |
DECISIONS.md |
架構決策的「為什麼」與放棄了什麼 |
bugs.md |
踩過的坑(症狀 / 根因 / 解法) |
runbook.md |
直接複製貼上的指令:build / 模擬器 / icon / 清快取 |
docs/camera-architecture.md |
相機頁技術設計(service 層、capture flow、HUD) |
docs/development-workflow.md |
這份文件:怎麼工作 / 思考順序 |
另外有 CLAUDE.md 給 Claude Code 開新 session 時自動載入,列出本 repo 特有的規則。
- 「現在長什麼樣」→
README.md - 「為什麼這樣選」→
DECISIONS.md - 「之後要做什麼」→
roadmap.md(不要散到 README / docs / 註解) - 「踩過什麼坑」→
bugs.md - 「該跑什麼指令」→
runbook.md - 「技術設計細節」→
docs/camera-architecture.md - 「怎麼工作」→ 這份
如果沒有特殊情況,最實際的日常循環是:
git status --short- 讀相關檔案
- 做最小正確修改
- 跑
xcodebuild - 看 build log
- 若是相機功能,做真機驗證
- 更新必要文件
- 再看一次
git status --short
下一步要做什麼集中在 ../roadmap.md。這份文件只描述「怎麼工作」,不再列待辦項。
需要新加 next-step 項目時,寫到 roadmap.md,不要寫到這裡。