上週在台南,我站在投影機前要 demo 一個 Gemini iPhone App 的功能。打開 QuickTime,按「新增影片錄製」改來源——出來的視窗左右兩條黑邊,手機畫面塞在中間像郵票一樣小。學員看不清楚我點哪裡。我手指比著螢幕說「就是這個按鈕」,整間教室前三排還算看得到,後面那七排只能猜。那一刻我想:怎麼會 2026 年了,把手機畫面投到 Mac 上這件事還這麼難。
回到台北那個週末,我用 Claude Code 寫了 iPhoneMirror。
為什麼我需要這個工具
講 AI 課這幾年,手機 demo 是逃不掉的環節——Gemini App、ChatGPT App、NotebookLM mobile、隨手拍照丟給 AI 的工作流,這些都得當場演給學員看。可選的方案就那幾種,每一個都讓我皺眉:
- QuickTime 影片錄製模式:Apple 內建,免費。問題:視窗預設黑邊一大圈、手機橫過來不會跟著轉、點擊的時候沒有任何視覺提示——學員看到游標在動就以為是我滑滑鼠,根本不知道我在 demo 手機。
- AirPlay / 螢幕鏡像:要連 WiFi。場館 WiFi 多爛我寫過一篇,這條路在偏鄉學校根本不通。
- Reflector / AirServer 這類商業軟體:要錢。Reflector 4 一次性 $19、AirServer 個人版年費。為了上幾堂課買訂閱,自己都覺得不對。
我要的東西其實很簡單:接條線、開 App、手機畫面填滿視窗、點哪裡螢幕上有個大游標讓學員看得到。就這樣。但沒有一個現成工具是這四件事都做對的。
它做了什麼
iPhoneMirror 是一個 macOS app,USB 接 iPhone / iPad 之後開起來,就會把手機螢幕用接近零延遲的速度投到 Mac 上。功能盤點:
我自己怎麼用
講課時的 setup 大概是這樣:iPhone 用 USB-C 接 MacBook、打開 iPhoneMirror、選單列把點擊特效設成「巨型游標」。把視窗拖到投影機畫面的左邊半,Typora 開課程大綱放右邊半。學員看到的是一支放大兩三倍的 iPhone 在動,我每點一下螢幕上就跳出一個大游標——後排不用瞇眼。
另一個用法是錄教學影片。Loom、ScreenStudio、QuickTime 抓整個 Mac 螢幕的時候,iPhoneMirror 的視窗就會被一起錄進去。比起 QuickTime 那個只能單獨錄手機畫面、後製還要再合成的流程,這個直接搞定。
# 想自己編譯(不裝 Xcode 也行,只要有 Command Line Tools)
mkdir -p iPhoneMirror.app/Contents/MacOS
mkdir -p iPhoneMirror.app/Contents/Resources
swiftc MirrorApp.swift -parse-as-library \
-o iPhoneMirror.app/Contents/MacOS/iPhoneMirror
cp Info.plist iPhoneMirror.app/Contents/
cp AppIcon.icns iPhoneMirror.app/Contents/Resources/
codesign --sign - --force --deep iPhoneMirror.app
背後的技術:那個 Apple 不想讓你用的 API
寫這支 app 最有趣的一段是搞清楚為什麼 macOS 沒辦法直接把 USB iPhone 當成 webcam。
答案是:能,但 Apple 預設關掉了。底層有一個叫做 CoreMediaIO 的 framework 管所有的視訊輸入裝置,裡面有一個 property——kCMIOHardwarePropertyAllowScreenCaptureDevices——當你把它設成 true,原本被藏起來的「USB 連接的 iOS 螢幕」就會在系統的 AVCaptureDevice 清單裡出現。出現之後,後面的事情就跟一般 USB 攝影機沒兩樣了——拉 video stream、丟去 SwiftUI 畫面、加上點擊特效層。
整個 app 是一支 Swift 檔,swiftc 直接編譯出 .app bundle,連 Xcode 專案都沒有。簽完碼就能跑。架構單純到讓人覺得這件事早該有人做。
用 Claude Code 寫這支 app 的工作流
我不是 Swift 工程師。我以前寫 Swift 的經驗是看 Hello World 範例。但 iPhoneMirror 的程式碼是這樣長出來的:
- 我描述痛點:「我想做一個 macOS app,USB 接 iPhone 就能投到 Mac 螢幕上,要無黑邊、要支援轉橫向、要點擊特效。」
- Claude Code 提架構:「macOS 不把 USB iOS 當 webcam,要先用 CoreMediaIO 開
kCMIOHardwarePropertyAllowScreenCaptureDevices,之後用 AVCaptureDevice + AVCaptureSession 拉 stream,SwiftUI 用 NSViewRepresentable 包 AVCaptureVideoPreviewLayer 顯示。」 - 第一版跑起來,我報告問題:「視窗有黑邊」「轉橫向不會跟」「我要點擊特效」「title bar 很醜可以拿掉嗎」。
- 它迭代:動態比例靠監聽
AVCaptureSession的 video dimension 變化、重設視窗 aspect ratio constraint;點擊特效用 NSEvent global monitor + overlay window;title bar 拿掉用NSWindow.styleMask = .borderless+ 自訂拖曳手勢。 - v1.2 的修正:macOS 26 升上去之後某些設備會黑畫面,這版專門修這個——這種 OS 升級踩到的雷,Claude Code 會去查 Apple 開發者論壇與 release notes,定位到是某個 capture session 的設定變了。
「The default isn't 'I'm going to prompt Claude'—the default is now 'I'm going to have Claude prompt itself.'」
(預設不是『我來下 prompt』,而是『我讓 Claude 自己下 prompt』。)—— Boris Cherny, Anthropic(Claude Code 共同作者)
我做的事是:定義要解的痛、看跑起來對不對、報告 bug、加新需求。Swift 語法、CoreMediaIO 文件、AVFoundation 細節——這些不是我會的,但也不需要我會。
給其他人的建議:你也可以這樣寫工具給自己
iPhoneMirror 不是我第一個用 Claude Code 寫的工具。同一個工作流我已經做過:
- MacPrism——menu bar 監控工具,連 Claude Code / Codex AI 額度都看得到
- WiFiScope——WiFi 頻譜分析工具,仿 $19 商業軟體 WiFi Explorer
- 那個數位官網——你正在看的這個,Web + Serverless + Redis
共同點是每一個都來自我自己的具體痛:監控不到 AI 額度、上課 WiFi 卡、QuickTime 投影黑邊一堆。我沒有先想「我要學 Swift」,是先想「這件事為什麼這麼煩」、再想「能不能自己做一個」。
給也想試的人三個建議:
- 從你自己的痛開始:不要做「想像中別人會用的工具」,做你今天上班會用到的。你會願意 debug 它一個週末,是因為你明天就要用。
- 不要怕陌生的技術棧:Swift、SwiftUI、CoreMediaIO、IOKit——這些字三年前我看到會頭暈。但會不會 Swift 跟能不能寫出 Swift app 是兩回事。前者你不會,後者你跟 Claude Code 一起就會。
- 寫完就開源、寫個 README、做個 icon。順手的事。十個人試用、回兩個 issue,這支工具會變得更好。
結語
下個月那場台南的課我會帶 iPhoneMirror 去。投影機左半放 Gemini App、右半放講義。後排學員看得到我點哪個按鈕,前排學員不用再側身。這件事兩個禮拜前還讓我皺眉,現在它不再是問題——這就是我說的「多了一個工程合夥人」。
需要的話拿去用。覺得有用幫我按個 star、覺得卡哪裡開個 issue 跟我說。