axiom-camera-capture-diag by charleswiltgen/axiom
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-camera-capture-diag针对 AVFoundation 相机问题的系统性故障排除:预览冻结、旋转错误、捕获缓慢、会话中断和权限问题。
核心原则:当相机无法正常工作时,问题通常出在:
在调试捕获逻辑之前,务必先检查线程处理和会话状态。
指示特定相机问题的症状:
| 症状 | 可能原因 |
|---|---|
| 预览显示黑屏 | 会话未启动、权限被拒绝、无相机输入 |
| 打开相机时 UI 冻结 | 在主线程上调用了 startRunning() |
| 来电时相机冻结 | 未处理中断 |
| 预览旋转错误 90° | 未使用 RotationCoordinator (iOS 17+) |
| 捕获的照片旋转错误 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 未将旋转角度应用于输出连接 |
| 前置摄像头照片未镜像 | 这是正确的!(预览镜像,照片不镜像) |
| "相机正被其他应用使用" | 另一个应用拥有独占访问权 |
| 捕获耗时 2 秒以上 | photoQualityPrioritization 设置为 .quality |
| 在 iPad 上会话无法启动 | 分屏视图 - 相机不可用 |
| 在旧版 iOS 上崩溃 | 使用 iOS 17+ API 但未进行可用性检查 |
在调查代码之前,运行这些诊断:
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(" Output: \(type(of: output))")
}
预期输出:
print("🧵 Thread check:")
// 设置会话时
sessionQueue.async {
print(" Setup thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}
// 启动会话时
sessionQueue.async {
print(" Start thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}
预期输出:
let status = AVCaptureDevice.authorizationStatus(for: .video)
print("🔐 Camera permission: \(status.rawValue)")
switch status {
case .authorized: print(" ✅ Authorized")
case .notDetermined: print(" ⚠️ Not yet requested")
case .denied: print(" ❌ Denied by user")
case .restricted: print(" ❌ Restricted (parental controls?)")
@unknown default: print(" ❓ Unknown")
}
// 添加临时观察器以查看中断
NotificationCenter.default.addObserver(
forName: .AVCaptureSessionWasInterrupted,
object: session,
queue: .main
) { notification in
if let reason = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? Int {
print("🚨 Interrupted: reason \(reason)")
}
}
Camera not working as expected?
│
├─ Black/frozen preview?
│ ├─ Check Step 1 (session state)
│ │ ├─ isRunning = false → See Pattern 1 (session not started)
│ │ ├─ inputs = 0 → See Pattern 2 (no camera input)
│ │ └─ isRunning = true, inputs > 0 → See Pattern 3 (preview layer)
│
├─ UI freezes when opening camera?
│ └─ Check Step 2 (threading)
│ └─ Main thread → See Pattern 4 (move to session queue)
│
├─ Camera freezes during use?
│ ├─ After phone call → See Pattern 5 (interruption handling)
│ ├─ In Split View (iPad) → See Pattern 6 (multitasking)
│ └─ Random freezes → See Pattern 7 (thermal pressure)
│
├─ Preview/photo rotated wrong?
│ ├─ Preview rotated → See Pattern 8 (RotationCoordinator preview)
│ ├─ Captured photo rotated → See Pattern 9 (capture rotation)
│ └─ Front camera "wrong" → See Pattern 10 (mirroring expected)
│
├─ Capture too slow?
│ ├─ 2+ seconds delay → See Pattern 11 (quality prioritization)
│ └─ Slight delay → See Pattern 12 (deferred processing)
│
├─ Permission issues?
│ ├─ Status: notDetermined → See Pattern 13 (request permission)
│ └─ Status: denied → See Pattern 14 (settings prompt)
│
└─ Crash on some devices?
└─ See Pattern 15 (API availability)
症状:黑屏预览,isRunning = false
常见原因:
startRunning()startRunning() 但会话没有输入诊断:
// Check if startRunning was called
print("isRunning before start: \(session.isRunning)")
session.startRunning()
print("isRunning after start: \(session.isRunning)")
修复:
// Ensure session is started on session queue
func startSession() {
sessionQueue.async { [self] in
guard !session.isRunning else { return }
// Verify we have inputs before starting
guard !session.inputs.isEmpty else {
print("❌ Cannot start - no inputs configured")
return
}
session.startRunning()
}
}
修复时间:10 分钟
症状:session.inputs.count = 0
常见原因:
AVCaptureDeviceInput 创建失败canAddInput() 返回 false诊断:
// Step through input setup
guard let camera = AVCaptureDevice.default(for: .video) else {
print("❌ No camera device found")
return
}
print("✅ Camera: \(camera.localizedName)")
do {
let input = try AVCaptureDeviceInput(device: camera)
print("✅ Input created")
if session.canAddInput(input) {
print("✅ Can add input")
} else {
print("❌ Cannot add input - check session preset compatibility")
}
} catch {
print("❌ Input creation failed: \(error)")
}
修复:确保在创建输入之前已授予权限,并包装在配置块中:
session.beginConfiguration()
// Add input here
session.commitConfiguration()
修复时间:15 分钟
症状:isRunning = true,输入已配置,但预览是黑屏
常见原因:
诊断:
print("Preview layer session: \(previewLayer.session != nil)")
print("Preview layer superlayer: \(previewLayer.superlayer != nil)")
print("Preview layer frame: \(previewLayer.frame)")
print("Preview layer connection: \(previewLayer.connection != nil)")
修复:
// Ensure preview layer is properly configured
previewLayer.session = session
previewLayer.videoGravity = .resizeAspectFill
// Ensure frame is set (common in SwiftUI)
previewLayer.frame = view.bounds
修复时间:10 分钟
症状:打开相机时 UI 冻结 1-3 秒
根本原因:startRunning() 是一个阻塞调用,在主线程上执行
诊断:
// If this prints on main thread, that's the problem
print("startRunning on thread: \(Thread.current)")
session.startRunning()
修复:
// Create dedicated serial queue
private let sessionQueue = DispatchQueue(label: "camera.session")
func startSession() {
sessionQueue.async { [self] in
session.startRunning()
}
}
修复时间:15 分钟
症状:相机正常工作,来电时冻结
根本原因:会话中断但未处理/无 UI 反馈
诊断:
// Check if session is still running after returning from call
print("Session running: \(session.isRunning)")
// Will be false during active call, true after call ends
修复:添加中断观察器(参见 camera-capture 技能模式 5)
关键点:中断结束后会话会自动恢复。您不需要再次调用 startRunning()。只需更新您的 UI。
修复时间:30 分钟
症状:iPad 进入分屏视图时相机停止工作
根本原因:多个前台应用运行时相机不可用
诊断:
// Check interruption reason
// InterruptionReason.videoDeviceNotAvailableWithMultipleForegroundApps
修复:显示适当的 UI 消息,并在用户退出分屏视图时恢复:
case .videoDeviceNotAvailableWithMultipleForegroundApps:
showMessage("Camera unavailable in Split View. Use full screen.")
修复时间:15 分钟
症状:相机随机停止,尤其是在长时间使用后
根本原因:设备发热,系统减少资源分配
诊断:
// Check thermal state
print("Thermal state: \(ProcessInfo.processInfo.thermalState.rawValue)")
// 0 = nominal, 1 = fair, 2 = serious, 3 = critical
修复:降低质量或显示冷却消息:
case .videoDeviceNotAvailableDueToSystemPressure:
// Reduce quality
session.sessionPreset = .medium
showMessage("Camera quality reduced due to device temperature")
修复时间:20 分钟
症状:预览旋转了 90°,与预期不符
根本原因:未使用 RotationCoordinator (iOS 17+) 或未观察更新
诊断:
print("Preview connection rotation: \(previewLayer.connection?.videoRotationAngle ?? -1)")
修复:
// Create and observe RotationCoordinator
let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: previewLayer)
// Set initial rotation
previewLayer.connection?.videoRotationAngle = coordinator.videoRotationAngleForHorizonLevelPreview
// Observe changes
observation = coordinator.observe(\.videoRotationAngleForHorizonLevelPreview) { [weak previewLayer] coord, _ in
DispatchQueue.main.async {
previewLayer?.connection?.videoRotationAngle = coord.videoRotationAngleForHorizonLevelPreview
}
}
修复时间:30 分钟
症状:预览看起来正确,但捕获的照片旋转了
根本原因:旋转角度未应用于照片输出连接
诊断:
if let connection = photoOutput.connection(with: .video) {
print("Photo connection rotation: \(connection.videoRotationAngle)")
}
修复:
func capturePhoto() {
// Apply current rotation to capture
if let connection = photoOutput.connection(with: .video) {
connection.videoRotationAngle = rotationCoordinator.videoRotationAngleForHorizonLevelCapture
}
photoOutput.capturePhoto(with: settings, delegate: self)
}
修复时间:15 分钟
症状:设计师说"前置摄像头照片与预览不匹配"
现实:这是正确的行为,不是错误。
解释:
如果业务需要镜像照片(自拍应用):
func mirrorImage(_ image: UIImage) -> UIImage? {
guard let cgImage = image.cgImage else { return nil }
return UIImage(cgImage: cgImage, scale: image.scale, orientation: .upMirrored)
}
修复时间:5 分钟(解释)或 15 分钟(如果需要镜像)
症状:照片捕获耗时 2 秒以上
根本原因:photoQualityPrioritization = .quality(某些设备的默认设置)
诊断:
print("Max quality prioritization: \(photoOutput.maxPhotoQualityPrioritization.rawValue)")
// Check what you're requesting in AVCapturePhotoSettings
修复:
var settings = AVCapturePhotoSettings()
// For fast capture (social/sharing)
settings.photoQualityPrioritization = .speed
// For balanced (general use)
settings.photoQualityPrioritization = .balanced
// Only use .quality when image quality is critical
修复时间:5 分钟
症状:希望获得最大响应速度(零快门延迟)
解决方案:启用延迟处理 (iOS 17+)
photoOutput.isAutoDeferredPhotoDeliveryEnabled = true
// Then handle proxy in delegate:
// - didFinishProcessingPhoto gives proxy for immediate display
// - didFinishCapturingDeferredPhotoProxy gives final image later
修复时间:30 分钟
症状:authorizationStatus = .notDetermined
修复:
// Must request before setting up session
Task {
let granted = await AVCaptureDevice.requestAccess(for: .video)
if granted {
setupSession()
}
}
修复时间:10 分钟
症状:authorizationStatus = .denied
修复:显示设置提示
func showSettingsPrompt() {
let alert = UIAlertController(
title: "Camera Access Required",
message: "Please enable camera access in Settings to use this feature.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
修复时间:15 分钟
症状:在 iOS 16 或更早版本上崩溃
根本原因:使用 iOS 17+ API 但未进行可用性检查
修复:
if #available(iOS 17.0, *) {
// Use RotationCoordinator
let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: preview)
} else {
// Fallback to deprecated videoOrientation
if let connection = previewLayer.connection {
connection.videoOrientation = .portrait
}
}
修复时间:20 分钟
| 症状 | 首先检查 | 可能模式 |
|---|---|---|
| 黑屏预览 | 步骤 1 (会话状态) | 1, 2, 或 3 |
| UI 冻结 | 步骤 2 (线程处理) | 4 |
| 来电时冻结 | 步骤 4 (中断) | 5 |
| 旋转错误 | 打印旋转角度 | 8 或 9 |
| 捕获缓慢 | 打印质量设置 | 11 |
| 访问被拒绝 | 步骤 3 (权限) | 14 |
| 旧版 iOS 上崩溃 | 检查 @available | 15 |
在升级相机问题之前:
基础:
线程处理:
权限:
旋转:
中断:
WWDC:2021-10247, 2023-10105
文档:/avfoundation/avcapturesession, /avfoundation/avcapturesessionwasinterruptednotification
技能:axiom-camera-capture, axiom-camera-capture-ref
每周安装数
99
仓库
GitHub 星标数
606
首次出现
2026年1月21日
安全审计
安装于
opencode85
codex79
gemini-cli78
cursor77
claude-code77
github-copilot75
Systematic troubleshooting for AVFoundation camera issues: frozen preview, wrong rotation, slow capture, session interruptions, and permission problems.
Core Principle : When camera doesn't work, the problem is usually:
Always check threading and session state BEFORE debugging capture logic.
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 |
Before investigating code, run these diagnostics:
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(" Output: \(type(of: output))")
}
Expected output :
print("🧵 Thread check:")
// When setting up session
sessionQueue.async {
print(" Setup thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}
// When starting session
sessionQueue.async {
print(" Start thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}
Expected output :
let status = AVCaptureDevice.authorizationStatus(for: .video)
print("🔐 Camera permission: \(status.rawValue)")
switch status {
case .authorized: print(" ✅ Authorized")
case .notDetermined: print(" ⚠️ Not yet requested")
case .denied: print(" ❌ Denied by user")
case .restricted: print(" ❌ Restricted (parental controls?)")
@unknown default: print(" ❓ Unknown")
}
// Add temporary observer to see interruptions
NotificationCenter.default.addObserver(
forName: .AVCaptureSessionWasInterrupted,
object: session,
queue: .main
) { notification in
if let reason = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? Int {
print("🚨 Interrupted: reason \(reason)")
}
}
Camera not working as expected?
│
├─ Black/frozen preview?
│ ├─ Check Step 1 (session state)
│ │ ├─ isRunning = false → See Pattern 1 (session not started)
│ │ ├─ inputs = 0 → See Pattern 2 (no camera input)
│ │ └─ isRunning = true, inputs > 0 → See Pattern 3 (preview layer)
│
├─ UI freezes when opening camera?
│ └─ Check Step 2 (threading)
│ └─ Main thread → See Pattern 4 (move to session queue)
│
├─ Camera freezes during use?
│ ├─ After phone call → See Pattern 5 (interruption handling)
│ ├─ In Split View (iPad) → See Pattern 6 (multitasking)
│ └─ Random freezes → See Pattern 7 (thermal pressure)
│
├─ Preview/photo rotated wrong?
│ ├─ Preview rotated → See Pattern 8 (RotationCoordinator preview)
│ ├─ Captured photo rotated → See Pattern 9 (capture rotation)
│ └─ Front camera "wrong" → See Pattern 10 (mirroring expected)
│
├─ Capture too slow?
│ ├─ 2+ seconds delay → See Pattern 11 (quality prioritization)
│ └─ Slight delay → See Pattern 12 (deferred processing)
│
├─ Permission issues?
│ ├─ Status: notDetermined → See Pattern 13 (request permission)
│ └─ Status: denied → See Pattern 14 (settings prompt)
│
└─ Crash on some devices?
└─ See Pattern 15 (API availability)
Symptom : Black preview, isRunning = false
Common causes :
startRunning() never calledstartRunning() called but session has no inputsDiagnostic :
// Check if startRunning was called
print("isRunning before start: \(session.isRunning)")
session.startRunning()
print("isRunning after start: \(session.isRunning)")
Fix :
// Ensure session is started on session queue
func startSession() {
sessionQueue.async { [self] in
guard !session.isRunning else { return }
// Verify we have inputs before starting
guard !session.inputs.isEmpty else {
print("❌ Cannot start - no inputs configured")
return
}
session.startRunning()
}
}
Time to fix : 10 min
Symptom : session.inputs.count = 0
Common causes :
AVCaptureDeviceInput creation failedcanAddInput() returned falseDiagnostic :
// Step through input setup
guard let camera = AVCaptureDevice.default(for: .video) else {
print("❌ No camera device found")
return
}
print("✅ Camera: \(camera.localizedName)")
do {
let input = try AVCaptureDeviceInput(device: camera)
print("✅ Input created")
if session.canAddInput(input) {
print("✅ Can add input")
} else {
print("❌ Cannot add input - check session preset compatibility")
}
} catch {
print("❌ Input creation failed: \(error)")
}
Fix : Ensure permission is granted BEFORE creating input, and wrap in configuration block:
session.beginConfiguration()
// Add input here
session.commitConfiguration()
Time to fix : 15 min
Symptom : isRunning = true, inputs configured, but preview is black
Common causes :
Diagnostic :
print("Preview layer session: \(previewLayer.session != nil)")
print("Preview layer superlayer: \(previewLayer.superlayer != nil)")
print("Preview layer frame: \(previewLayer.frame)")
print("Preview layer connection: \(previewLayer.connection != nil)")
Fix :
// Ensure preview layer is properly configured
previewLayer.session = session
previewLayer.videoGravity = .resizeAspectFill
// Ensure frame is set (common in SwiftUI)
previewLayer.frame = view.bounds
Time to fix : 10 min
Symptom : UI freezes for 1-3 seconds when camera opens
Root cause : startRunning() is a blocking call executed on main thread
Diagnostic :
// If this prints on main thread, that's the problem
print("startRunning on thread: \(Thread.current)")
session.startRunning()
Fix :
// Create dedicated serial queue
private let sessionQueue = DispatchQueue(label: "camera.session")
func startSession() {
sessionQueue.async { [self] in
session.startRunning()
}
}
Time to fix : 15 min
Symptom : Camera works, then freezes when phone call comes in
Root cause : Session interrupted but no handling/UI feedback
Diagnostic :
// Check if session is still running after returning from call
print("Session running: \(session.isRunning)")
// Will be false during active call, true after call ends
Fix : Add interruption observers (see camera-capture skill Pattern 5)
Key point : Session AUTOMATICALLY resumes after interruption ends. You don't need to call startRunning() again. Just update your UI.
Time to fix : 30 min
Symptom : Camera stops working when iPad enters Split View
Root cause : Camera not available with multiple foreground apps
Diagnostic :
// Check interruption reason
// InterruptionReason.videoDeviceNotAvailableWithMultipleForegroundApps
Fix : Show appropriate UI message and resume when user exits Split View:
case .videoDeviceNotAvailableWithMultipleForegroundApps:
showMessage("Camera unavailable in Split View. Use full screen.")
Time to fix : 15 min
Symptom : Camera stops randomly, especially after prolonged use
Root cause : Device getting hot, system reducing resources
Diagnostic :
// Check thermal state
print("Thermal state: \(ProcessInfo.processInfo.thermalState.rawValue)")
// 0 = nominal, 1 = fair, 2 = serious, 3 = critical
Fix : Reduce quality or show cooling message:
case .videoDeviceNotAvailableDueToSystemPressure:
// Reduce quality
session.sessionPreset = .medium
showMessage("Camera quality reduced due to device temperature")
Time to fix : 20 min
Symptom : Preview is rotated 90° from expected
Root cause : Not using RotationCoordinator (iOS 17+) or not observing updates
Diagnostic :
print("Preview connection rotation: \(previewLayer.connection?.videoRotationAngle ?? -1)")
Fix :
// Create and observe RotationCoordinator
let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: previewLayer)
// Set initial rotation
previewLayer.connection?.videoRotationAngle = coordinator.videoRotationAngleForHorizonLevelPreview
// Observe changes
observation = coordinator.observe(\.videoRotationAngleForHorizonLevelPreview) { [weak previewLayer] coord, _ in
DispatchQueue.main.async {
previewLayer?.connection?.videoRotationAngle = coord.videoRotationAngleForHorizonLevelPreview
}
}
Time to fix : 30 min
Symptom : Preview looks correct, but captured photo is rotated
Root cause : Rotation angle not applied to photo output connection
Diagnostic :
if let connection = photoOutput.connection(with: .video) {
print("Photo connection rotation: \(connection.videoRotationAngle)")
}
Fix :
func capturePhoto() {
// Apply current rotation to capture
if let connection = photoOutput.connection(with: .video) {
connection.videoRotationAngle = rotationCoordinator.videoRotationAngleForHorizonLevelCapture
}
photoOutput.capturePhoto(with: settings, delegate: self)
}
Time to fix : 15 min
Symptom : Designer says "front camera photo doesn't match preview"
Reality : This is CORRECT behavior, not a bug.
Explanation :
If business requires mirrored photos (selfie apps):
func mirrorImage(_ image: UIImage) -> UIImage? {
guard let cgImage = image.cgImage else { return nil }
return UIImage(cgImage: cgImage, scale: image.scale, orientation: .upMirrored)
}
Time to fix : 5 min (explanation) or 15 min (if mirroring required)
Symptom : Photo capture takes 2+ seconds
Root cause : photoQualityPrioritization = .quality (default for some devices)
Diagnostic :
print("Max quality prioritization: \(photoOutput.maxPhotoQualityPrioritization.rawValue)")
// Check what you're requesting in AVCapturePhotoSettings
Fix :
var settings = AVCapturePhotoSettings()
// For fast capture (social/sharing)
settings.photoQualityPrioritization = .speed
// For balanced (general use)
settings.photoQualityPrioritization = .balanced
// Only use .quality when image quality is critical
Time to fix : 5 min
Symptom : Want maximum responsiveness (zero-shutter-lag)
Solution : Enable deferred processing (iOS 17+)
photoOutput.isAutoDeferredPhotoDeliveryEnabled = true
// Then handle proxy in delegate:
// - didFinishProcessingPhoto gives proxy for immediate display
// - didFinishCapturingDeferredPhotoProxy gives final image later
Time to fix : 30 min
Symptom : authorizationStatus = .notDetermined
Fix :
// Must request before setting up session
Task {
let granted = await AVCaptureDevice.requestAccess(for: .video)
if granted {
setupSession()
}
}
Time to fix : 10 min
Symptom : authorizationStatus = .denied
Fix : Show settings prompt
func showSettingsPrompt() {
let alert = UIAlertController(
title: "Camera Access Required",
message: "Please enable camera access in Settings to use this feature.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
Time to fix : 15 min
Symptom : Crash on iOS 16 or earlier
Root cause : Using iOS 17+ APIs without availability check
Fix :
if #available(iOS 17.0, *) {
// Use RotationCoordinator
let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: preview)
} else {
// Fallback to deprecated videoOrientation
if let connection = previewLayer.connection {
connection.videoOrientation = .portrait
}
}
Time to fix : 20 min
| Symptom | Check First | Likely Pattern |
|---|---|---|
| Black preview | Step 1 (session state) | 1, 2, or 3 |
| UI freezes | Step 2 (threading) | 4 |
| Freezes on call | Step 4 (interruptions) | 5 |
| Wrong rotation | Print rotation angle | 8 or 9 |
| Slow capture | Print quality setting | 11 |
| Denied access | Step 3 (permissions) | 14 |
| Crash on old iOS | Check @available | 15 |
Before escalating camera issues:
Basics :
Threading :
Permissions :
Rotation :
Interruptions :
WWDC : 2021-10247, 2023-10105
Docs : /avfoundation/avcapturesession, /avfoundation/avcapturesessionwasinterruptednotification
Skills : axiom-camera-capture, axiom-camera-capture-ref
Weekly Installs
99
Repository
GitHub Stars
606
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode85
codex79
gemini-cli78
cursor77
claude-code77
github-copilot75
SAP Fiori Tools 开发指南:简化 Fiori Elements 和 SAPUI5 应用开发
124 周安装
股票与加密货币分析工具 - 投资组合管理与技术分析 (v5.0)
124 周安装
WOLF HOWL v2:自动化交易复盘与策略优化工具 - 数据驱动的每日分析
124 周安装
Docker Compose 编排指南:多容器应用部署、健康检查与环境管理(2024-2025)
124 周安装
Redis状态管理实战指南:缓存、会话、分布式锁与实时消息系统
81 周安装
BubbleTea 代码审查指南:Go TUI 应用最佳实践与常见错误排查
124 周安装