AVCaptureDeviceInput在解包Optional值时意外发现nil

问题描述 投票:0回答:1

我正在尝试获取捕获设备的图像,但它继续由if let input...返回零,我找不到解决方案。

它试图捕获错误,但它立即兑现..

let backCamera = AVCaptureDevice.default(for: AVMediaType.video)

    do {
        if let input = try AVCaptureDeviceInput(device: backCamera!) as? AVCaptureInput {
            if (captureSession?.canAddInput(input))! {
                captureSession?.addInput(input)

                stillImageOutput = AVCapturePhotoOutput()
                let settings = AVCapturePhotoSettings()
                let settingsFormat = [AVVideoCodecKey : AVVideoCodecType.jpeg]
                settings.previewPhotoFormat = settingsFormat

                stillImageOutput?.capturePhoto(with: settings, delegate: self as! AVCapturePhotoCaptureDelegate)

                if (captureSession?.canAddOutput(stillImageOutput!))! {
                    captureSession?.addOutput(stillImageOutput!)

                    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                    previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspect
                    previewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
                    cameraView.layer.addSublayer(previewLayer!)

                    captureSession?.startRunning()
                }
            }
        }


    } catch let error as NSError {
        print("Error: \(error)")
    }
swift null
1个回答
1
投票

这不是你的错误抛出导致崩溃 - 这是你所有的力量解开。 backCameracaptureSessionstillImageOutputpreviewLayer都是Optionals,但你每次都要强行解开所有这些。为什么不使用保护语句或可选绑定来避免那些崩溃?最终你不能运行任何代码,如果这些项是零,所以我会像这样重构你的代码:

//Use guard to make sure you have a non-nil captureSession and a default device for .video
guard let captureSession = captureSession, let backCamera = AVCaptureDevice.default(for: AVMediaType.video) else { return }

do {
    if let input = try AVCaptureDeviceInput(device: backCamera) as? AVCaptureInput {
        if (captureSession.canAddInput(input)) {
            captureSession.addInput(input)
            stillImageOutput = AVCapturePhotoOutput()

            //Since stillImageOutput is an Optional I'm putting in another guard just to avoid having to deal with it as an Optional
            guard let stillImageOutput = stillImageOutput else { return }

            let settings = AVCapturePhotoSettings()
            let settingsFormat = [AVVideoCodecKey : AVVideoCodecType.jpeg]
            settings.previewPhotoFormat = settingsFormat

            stillImageOutput.capturePhoto(with: settings, delegate: self as! AVCapturePhotoCaptureDelegate)

            if (captureSession.canAddOutput(stillImageOutput)) {
                captureSession.addOutput(stillImageOutput)

                previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

                //Same as above - since you declared previewLayer as Optional I'll guard so I don't have to deal with it as an Optional
                guard let previewLayer = previewLayer else { return }

                previewLayer.videoGravity = AVLayerVideoGravity.resizeAspect
                previewLayer.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
                cameraView.layer.addSublayer(previewLayer)
                captureSession.startRunning()
            }
        }
    }
} catch let error {
    print("Error: \(error)")
}

老实说,其中一些有点矫枉过正,所以这取决于个人的偏好,但是像AVCaptureDevice.default...这样的东西真的可能会或者可能不会是nil,具体取决于实际设备你可能不想让它崩溃如果它不存在。

© www.soinside.com 2019 - 2024. All rights reserved.