You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4 相机访问方法及扫码报错‘Failed to get the camera device’求助

1. 如何在Swift 4中访问相机?

我来给你捋捋在Swift 4里访问相机的常规步骤,亲测靠谱:

  • 第一步:配置相机权限
    必须在Info.plist中添加相机权限描述,不然系统会直接拒绝访问。右键Info.plist选择“Open As -> Source Code”,添加以下代码:

    <key>NSCameraUsageDescription</key>
    <string>需要访问相机进行拍摄/扫码操作</string>
    

    字符串内容要明确告诉用户为什么需要相机权限,别写空字符串或者模糊的描述。

  • 第二步:用AVFoundation框架实现访问逻辑
    Swift 4中访问相机主要依赖AVFoundation框架,下面是核心代码示例:

    import AVFoundation
    import UIKit
    
    class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
        var captureSession: AVCaptureSession!
        var previewLayer: AVCaptureVideoPreviewLayer!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // 先请求相机权限
            AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
                DispatchQueue.main.async {
                    guard granted else {
                        // 权限被拒绝,提示用户去设置里开启
                        let alert = UIAlertController(title: "权限不足", message: "请在设置中开启相机权限", preferredStyle: .alert)
                        alert.addAction(UIAlertAction(title: "确定", style: .default))
                        self?.present(alert, animated: true)
                        return
                    }
                    // 权限通过,初始化相机会话
                    self?.setupCameraSession()
                }
            }
        }
    
        func setupCameraSession() {
            captureSession = AVCaptureSession()
            captureSession.sessionPreset = .high
    
            // 获取后置相机设备
            guard let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
                print("无法获取相机设备")
                return
            }
    
            // 创建输入流
            guard let input = try? AVCaptureDeviceInput(device: captureDevice) else {
                print("无法创建相机输入")
                return
            }
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
            }
    
            // 创建输出流(如果需要处理视频帧,比如扫码)
            let videoOutput = AVCaptureVideoDataOutput()
            videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "cameraQueue"))
            if captureSession.canAddOutput(videoOutput) {
                captureSession.addOutput(videoOutput)
            }
    
            // 添加预览层到视图
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer.frame = view.bounds
            previewLayer.videoGravity = .resizeAspectFill
            view.layer.addSublayer(previewLayer)
    
            // 启动会话
            captureSession.startRunning()
        }
    
        // 实现视频帧代理方法(如果需要处理帧数据)
        func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
            // 在这里处理每帧视频数据,比如扫码逻辑
        }
    }
    
  • 注意事项

    • 相机操作必须在真机上测试,模拟器没有相机硬件;
    • 权限请求是异步的,一定要等用户授权后再初始化相机会话;
    • 如果需要切换前后摄像头,可以用AVCaptureDevice.DiscoverySession枚举可用设备。

2. 解决“Failed to get the camera device”报错问题

我之前帮朋友排查过类似的问题,正好也用过你提到的这个扫码仓库代码,给你几个针对性的排查方向:

可能的原因&解决方法:

  • 权限配置是否真的正确?
    有时候看似加了权限,其实键名拼写错误或者描述为空。确认Info.plist中的NSCameraUsageDescription(对应可视化界面的“Privacy - Camera Usage Description”)存在,且字符串内容不为空。有些iOS版本会因为描述为空直接拒绝权限,导致无法获取相机。

  • 相机设备获取逻辑不够兼容
    原仓库代码可能用了AVCaptureDevice.default(for: .video)来获取相机,但有些旧设备(比如iPhone SE初代)或者特殊机型上,这个方法可能返回nil。建议把获取设备的代码改成更稳妥的写法:

    // 替换原有的获取相机设备代码
    let discoverySession = AVCaptureDevice.DiscoverySession(
        deviceTypes: [.builtInWideAngleCamera],
        mediaType: .video,
        position: .back
    )
    guard let captureDevice = discoverySession.devices.first else {
        print("Failed to get the camera device")
        return
    }
    

    这种方式会枚举所有可用的后置广角相机,兼容性更好。

  • 权限请求时机不对
    有些代码会在权限请求还没完成时就初始化相机,导致权限还没通过就尝试获取设备。确保把相机初始化的代码放在权限请求的completion handler里,并且切换到主线程执行(比如我第一个问题里的代码示例那样)。

  • 硬件或系统问题
    试试重启你的真机,有时候后台有其他应用占用相机,会导致当前应用无法获取;或者换一台真机测试,排除硬件故障的可能。

  • 检查项目依赖
    确认你的项目已经正确导入AVFoundation框架,用CocoaPods安装的话,仓库应该已经配置好了,但手动导入的话要确保在Build Phases的Link Binary With Libraries里添加了AVFoundation.framework。

内容的提问来源于stack exchange,提问作者OCTAVIAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:28:26