错误线程1:致命错误:展开一个可选值时意外发现nil吗?

时间:2018-08-05 17:58:12

标签: ios iphone swift warnings

是的,我知道有人问过类似的问题,但是我已经遍历了所有可以找到的问题,但仍然无法解决此问题。 Maby我遇到的这个问题也会帮助其他人。

我正在尝试制作相机应用程序,但是当我运行该应用程序时,它立即失败。我已标记出失败的地方,并给我以下警告...

  

线程1:致命错误:在展开可选值时意外发现nil

这是代码,我已经标记了得到警告的部分:

    import UIKit
import AVFoundation

class ViewController: UIViewController {

    var captureSession = AVCaptureSession()

    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?
    var currentCamera: AVCaptureDevice?

    var photoOutput: AVCapturePhotoOutput?

    var cameraPreviewlayer: AVCaptureVideoPreviewLayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        setupCaptureSession()
        setupInputOutput()
        setupPreviewLayer()
        startRunningCaptureSession()

        // Do any additional setup after loading the view, typically from a nib.
    }

    func setupCaptureSession() {
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
    }

    func setupDevice() {
        let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)

        let devices = deviceDiscoverySession.devices

        for device in devices {
            if device.position == AVCaptureDevice.Position.back {
                backCamera = device
            } else if device.position == AVCaptureDevice.Position.front {
                frontCamera = device
            }
        }

        currentCamera = backCamera
    }

    func setupInputOutput() {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!) //Here is the error-------
            captureSession.addInput(captureDeviceInput)
            photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)

        } catch {
            print(error)
        }
    }

    func setupPreviewLayer(){
        cameraPreviewlayer = AVCaptureVideoPreviewLayer(session: captureSession)
        cameraPreviewlayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraPreviewlayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
        cameraPreviewlayer?.frame = self.view.frame
        self.view.layer.insertSublayer(cameraPreviewlayer!, at: 0)
    }

    func startRunningCaptureSession() {
        captureSession.startRunning()
    }

    @IBAction func CameraButton_TouchUpInside(_ sender: Any) {

        performSegue(withIdentifier: "showPhoto_Segue", sender: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

2 个答案:

答案 0 :(得分:0)

您不会在代码中的任何地方调用setupDevice(),即使已调用currentCamera,也总是将backCamera设置为nil,如果设备未将setupDevice()设置为viewDidLoad()有后置摄像头。

只需将 override func viewDidLoad() { super.viewDidLoad() setupCaptureSession() setupDevice() setupInputOutput() setupPreviewLayer() startRunningCaptureSession() } 调用添加到您的use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; public function indexAction(Request $request) { $em = $this->getDoctrine()->getManager(); /** * confirm that the user indeed owns * phone number related to the invoice (code verification) */ //create a user for this task only and fetch it $user = $em->getRepository(User::class)->find(1); //firewall name used for authentication in security.yml $firewall = "main_secured_area"; $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles()); $this->get('security.token_storage')->setToken($token); $this->get('session')->set("_security_$firewall", serialize($token)); //$lifetime takes number of seconds to define session timeout 15min = 900sec $this->container->get('session')->migrate($destroy = false, $lifetime = 900); //fire the login event manually $event = new InteractiveLoginEvent($request, $token); $this->get("event_dispatcher")->dispatch("security.interactive_login", $event); return $this->render('default/index.html.twig'); }

MailChimp error: The requested resource could not be found. url: https://us4.api.mailchimp.com/3.0/ecommerce/stores/1/promo-rules/24/promo-codes/1 data: {\"redemption_url\":\"https:\\/\\/natureldeluxe.be\\/\",\"enabled\":true,\"code\":\"10NEWS1\"}

MailChimp error: The requested resource could not be found. url: https://us4.api.mailchimp.com/3.0/ecommerce/stores/1/promo-rules/24 data: {\"title\":\"10% korting\",\"description\":\"\",\"starts_at\":\"2018-05-30 10:00:00\",\"ends_at\":\"2019-12-31 23:59:00\",\"enabled\":true,\"type\":\"percentage\",\"amount\":0.1,\"target\":\"total\"}

答案 1 :(得分:0)

在调用setupDevice()之前,您应该在override func viewDidLoad()中调用setupInputOutput(),以如下方式为currentCamera分配一个值:

override func viewDidLoad() {
    super.viewDidLoad()

    setupCaptureSession()
    setupDevice()
    setupInputOutput()
    setupPreviewLayer()
    startRunningCaptureSession()

}