Drag real iPhone screenshots into your coding agent.
PhoneSnap is a small macOS menu bar app for AI-assisted iOS work. Plug in a trusted iPhone over USB, or run the generated iOS Shortcut over Wi-Fi, and PhoneSnap turns real device screenshots into draggable Mac thumbnails.
The goal is simple: when your agent needs to understand a broken layout, a weird state, or a real-device visual bug, you should be able to take a screenshot and drop it straight into Codex, Cursor, Claude, ChatGPT, Slack, or an issue.
The sample screenshots below are rendered from PhoneSnap's real AppKit views with generated phone-screen content, so they show the app without exposing anyone's device data.
When the Shortcut sends several screenshots, PhoneSnap keeps a Recent from iPhone strip open so each image can be dragged into an agent one by one.
- Run PhoneSnap on the Mac.
- Take a screenshot on a real iPhone.
- Drag the thumbnail into your agent chat or issue.
- Ask for the fix with the real UI in view.
USB is the primary path because macOS exposes a trusted plugged-in iPhone as a camera-class device through ImageCaptureCore. The wireless Shortcut is a manual fallback for times when USB is inconvenient.
- macOS 13+
- Swift 5.9+ / Xcode 15+ to build
- iPhone or iPad that appears to macOS through ImageCaptureCore
- USB or USB-C cable for wired mode
- Same Wi-Fi/LAN for wireless Shortcut mode
Download the latest PhoneSnap.zip from Releases, unzip it, then open PhoneSnap.app.
PhoneSnap is not notarized yet, so macOS may block the first launch. If that happens, right-click PhoneSnap.app, choose Open, then confirm.
To build from source instead:
git clone https://github.com/Aqu1bp/PhoneSnap.git
cd PhoneSnap
./scripts/build-app.sh
open ./PhoneSnap.appA small iPhone icon appears in the menu bar. The app is running.
- Plug your iPhone into the Mac.
- Unlock the iPhone.
- If prompted, tap Trust This Computer.
- Take a screenshot on the iPhone.
- Drag the Mac thumbnail into Codex, Cursor, Claude, ChatGPT, Slack, or wherever the agent can see images.
Behind the scenes, PhoneSnap uses Apple's ImageCaptureCore framework. macOS exposes a trusted, plugged-in iPhone as a camera-class device, so PhoneSnap can watch for new camera-roll items after startup, filter likely screenshots, save them locally, copy them to the clipboard, and show the thumbnail.
- Open the PhoneSnap menu bar item.
- Choose Set Up Wireless Shortcut....
- Scan the setup QR code with the iPhone Camera, or copy/open the setup URL. If the
.localhostname will not load on your network, switch the QR to IP address in the setup window. - On the iPhone, open
PhoneSnap.shortcutand add it in Shortcuts. - Take a screenshot, then run the PhoneSnap Shortcut from Shortcuts, Action Button, Back Tap, Control Center, or the Home Screen.
The Shortcut is generated locally by the Mac app. It asks Photos for the latest screenshot batch (10 by default, configurable with PHONESNAP_BATCH_COUNT) and posts each image to POST /api/v1/upload/<pairId> with a persisted bearer token, so the user does not type the URL, method, headers, or body. As uploads arrive, PhoneSnap updates the floating Recent from iPhone panel with draggable thumbnails. This remains useful when USB is unavailable.
Existing installed PhoneSnap Shortcuts should be removed and reinstalled from the setup page to get batch behavior.
- Primary path: a trusted iPhone connected to the Mac over USB.
- Fallback path: a locally generated, signed iOS Shortcut that sends a screenshot batch over the LAN.
- Deprecated/experimental: automatic wireless senders embedded in the foreground app being built.
- Deliberately not used: GitHub Gist rendezvous, third-party services, iCloud, or manual Shortcut URL/header/body entry.
The senders/ packages are deprecated as a main product path for now. They are kept as experimental references for foreground-app debug builds that post directly to the Mac upload endpoint. The menu no longer exposes a happy-path dev sender config action.
- Appears bottom-right of the screen containing the cursor.
- Auto-copies the screenshot to the clipboard on arrival.
- Shows action buttons for copy (⌘C), save to Downloads (⌘S), and delete to Trash (⌘⌫). Click the image to open it in Preview.
- Drag the image directly into agent apps, chat apps, issue trackers, or any file drop target.
- Press ESC or click the close button to dismiss.
- Auto-fades after 8 seconds; hovering resets the timer.
- Wireless Shortcut uploads do not show the wired single thumbnail by default.
- The Mac opens a floating Recent from iPhone panel immediately and updates it as more screenshots arrive.
- Each panel thumbnail can be dragged into agent apps and file drop targets.
- Click a panel thumbnail to copy it to the clipboard.
- Double-click a panel thumbnail to open it in Preview.
- The latest wireless upload is also written to the pasteboard for paste workflows.
By default:
~/Pictures/PhoneSnap/Screenshot YYYY-MM-DD at HH.MM.SS.SSS.png
Override the folder when launching:
PHONESNAP_DIR=~/Desktop/screenshots open ./PhoneSnap.app| Goal | Command |
|---|---|
| Build + launch | ./scripts/build-app.sh && open ./PhoneSnap.app |
| Run from source with logs | swift run PhoneSnap |
| Run the debug binary | .build/debug/PhoneSnap |
| Stop the app | Menu bar item -> Quit, or pkill -f PhoneSnap |
| Change save folder | PHONESNAP_DIR=~/wherever open ./PhoneSnap.app |
| Change wireless port | PHONESNAP_WIRELESS_PORT=18472 open ./PhoneSnap.app |
| Change Shortcut batch size (1-50, default 10) | PHONESNAP_BATCH_COUNT=20 open ./PhoneSnap.app, then re-download and re-add the Shortcut |
iPhone over USB
screenshot saved to camera roll
-> ImageCaptureCore didAdd callback
-> PhoneSnap downloads the new item
-> saves PNG to ~/Pictures/PhoneSnap
-> writes PNG/TIFF/file URL to NSPasteboard
-> shows a floating NSPanel thumbnail
iPhone over Wi-Fi
user runs generated PhoneSnap Shortcut
-> Shortcut reads the latest screenshot batch from Photos
-> repeats over the screenshots
-> POSTs each image to the Mac receiver with Authorization: Bearer <token>
-> Mac saves each PNG, updates pasteboard to the latest upload
-> Mac shows the Recent from iPhone batch panel
iPhone over Wi-Fi experimental
foreground app includes deprecated debug PhoneSnap sender
-> sender snapshots its active app UI
-> POSTs raw PNG to the Mac receiver with Authorization: Bearer <token>
| Symptom | Fix |
|---|---|
| Nothing appears after taking a screenshot | Unlock the iPhone, reconnect the cable, and accept Trust This Computer if prompted. |
| Dragging into an agent does not attach the image | Use the copy button or paste with Command-V; PhoneSnap writes PNG, TIFF, and file URL pasteboard types. |
| Old photos appear | Quit and reopen the app, then take a fresh screenshot. |
| Clipboard paste fails | Use the thumbnail copy button; if it still fails, run from terminal with swift run PhoneSnap and check logs. |
| App does not launch | Rebuild with ./scripts/build-app.sh. |
| Thumbnail appears on the wrong display | Move the mouse to the target display before taking the screenshot. |
| Wireless setup page does not load | Keep the Mac app running and put both devices on the same LAN. If macOS asked about incoming connections, allow PhoneSnap in System Settings → Network → Firewall. If the .local name will not resolve, switch the setup window QR to IP address. |
| Wireless receiver is unavailable | Another process may be using the port. Quit the other process or relaunch with PHONESNAP_WIRELESS_PORT=<port>. Wired mode should still work. |
| Shortcut used to work but now fails silently | If it was installed from the IP address URL, the Mac's IP likely changed. Rerun setup and re-add the Shortcut; prefer the .local hostname URL when it loads. |
| Shortcut runs but nothing appears on the Mac | Confirm screenshots exist in Photos, both devices are on the same LAN, and Shortcuts has local-network permission (iPhone Settings → Privacy & Security → Local Network). |
| Shortcut download fails | Run from terminal with swift run PhoneSnap; the setup route reports /usr/bin/shortcuts sign errors instead of crashing. If signing fails or times out on a fresh Mac, open the Shortcuts app once and retry. |
- Wired USB remains the primary supported path.
- Shortcut wireless is manual-triggered and remains a fallback.
- Existing installed Shortcuts need reinstall to get the latest batch upload behavior.
- Dev senders are deprecated/experimental and no longer exposed in the main menu.
- Wireless requires the Mac app to be running and reachable from the iPhone on the local network.
- Shortcut signing depends on
/usr/bin/shortcuts sign --mode anyone. - Wired mode shows one thumbnail at a time. A new wired screenshot dismisses the old wired thumbnail.
- Screenshot detection uses dimensions/aspect-ratio heuristics to avoid importing normal camera photos.
- No app sandbox and no notarization. First launch may require right-click -> Open or removing quarantine metadata.
- No automated iPhone end-to-end test; full wired/wireless verification requires a real trusted iPhone.
PhoneSnap/
├── .github/ CI, issue templates, repo automation
├── docs/ architecture, research notes, test plan
├── senders/ debug embedded sender references
│ ├── apple-ios native UIKit Swift Package
│ ├── expo Expo prototype
│ ├── react-native intended API stub
│ └── flutter intended API stub
├── Sources/PhoneSnap/ macOS menu bar app
│ ├── AppDelegate.swift app lifecycle and delivery pipeline
│ ├── CameraBridge.swift ImageCaptureCore USB watcher
│ ├── ImageStore.swift save received bytes as PNG
│ ├── Pasteboard.swift multi-type clipboard write
│ ├── StatusItemController.swift menu bar item
│ ├── WirelessReceiver.swift local HTTP setup/upload receiver
│ ├── WirelessBatchPresenter... Recent from iPhone batch panel
│ ├── WirelessSetupWindow... setup QR/window UI
│ ├── WirelessShortcut... signed Shortcut generation
│ ├── ThumbnailPresenter.swift wires saved image to thumbnail window
│ ├── ThumbnailWindowController borderless floating NSPanel
│ ├── ThumbnailView.swift image view, actions, drag-out
│ └── Log.swift stderr logging
├── Sources/ICProbe/ ImageCaptureCore probe utility
├── Sources/UsbmuxdProbe/ usbmuxd probe utility
├── scripts/build-app.sh wraps the SwiftPM binary into PhoneSnap.app
├── scripts/smoke-test.sh wireless receiver smoke test used by CI
├── Package.swift
├── README.md
└── ROADMAP.md
Wireless mode runs a plain-HTTP receiver on your LAN, protected by a random pair ID and bearer token. Read SECURITY.md for the threat model before using it on shared networks. Wired mode opens no network listeners.
See CONTRIBUTING.md and ROADMAP.md. Small, focused PRs that improve reliability around real-device capture are especially useful.

