camera freezes, preview rotated wrong, capture slow, session interrupted, black preview, front camera mirrored, camera not starting, AVCaptureSession errors, startRunning blocks, phone call interrupts camera
View on GitHubSelect agents to install to:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-camera-capture-diag/SKILL.md -a claude-code --skill axiom-camera-capture-diagInstallation paths:
.claude/skills/axiom-camera-capture-diag/# Camera Capture Diagnostics
Systematic troubleshooting for AVFoundation camera issues: frozen preview, wrong rotation, slow capture, session interruptions, and permission problems.
## Overview
**Core Principle**: When camera doesn't work, the problem is usually:
1. **Threading** (session work on main thread) - 35%
2. **Session lifecycle** (not started, interrupted, not configured) - 25%
3. **Rotation** (deprecated APIs, missing coordinator) - 20%
4. **Permissions** (denied, not requested) - 15%
5. **Configuration** (wrong preset, missing input/output) - 5%
**Always check threading and session state BEFORE debugging capture logic.**
## Red Flags
Symptoms that indicate camera-specific issues:
| Symptom | Likely Cause |
|---------|--------------|
| Preview shows black screen | Session not started, permission denied, no camera input |
| UI freezes when opening camera | `startRunning()` called on main thread |
| Camera freezes on phone call | No interruption handling |
| Preview rotated 90° wrong | Not using RotationCoordinator (iOS 17+) |
| Captured photo rotated wrong | Rotation angle not applied to output connection |
| Front camera photo not mirrored | This is correct! (preview mirrors, photo does not) |
| "Camera in use by another app" | Another app has exclusive access |
| Capture takes 2+ seconds | `photoQualityPrioritization` set to `.quality` |
| Session won't start on iPad | Split View - camera unavailable |
| Crash on older iOS | Using iOS 17+ APIs without availability check |
## Mandatory First Steps
Before investigating code, run these diagnostics:
### Step 1: Check Session State
```swift
print("📷 Session state:")
print(" isRunning: \(session.isRunning)")
print(" inputs: \(session.inputs.count)")
print(" outputs: \(session.outputs.count)")
for input in session.inputs {
if let deviceInput = input as? AVCaptureDeviceInput {
print(" Input: \(deviceInput.device.localizedName)")
}
}
for output in session.outputs {
print(" O