Search code examples
iosswift3seguexcode8uistoryboardsegue

Why am I getting a seg fault in this line of code when I try to segue from storyboard?


So, I am trying to segue a button in storyboard to another ViewController. However, every time I tap the button, the app just crashes. This is the line of code that gets highlighted when the app crashes.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    let barcodeViewController: BarcodeReaderViewController = segue.destination as! BarcodeReaderViewController
    barcodeViewController.delegate = self

}

This is my BarCodeVC

import UIKit
import AVFoundation

protocol BarcodeDelegate {
  func barcodeReaded(barcode: String)
}

class BarcodeViewController: UIViewController, 
                             AVCaptureMetadataOutputObjectsDelegate {

var delegate: BarcodeDelegate?

var videoCaptureDevice: AVCaptureDevice = 
 AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
var device = AVCaptureDevice.defaultDevice(withMediaType: 
  AVMediaTypeVideo)
var output = AVCaptureMetadataOutput()
var previewLayer: AVCaptureVideoPreviewLayer?

var captureSession = AVCaptureSession()
var code: String?

override func viewDidLoad() {
  super.viewDidLoad()

  self.view.backgroundColor = UIColor.clear
  self.setupCamera()
}

private func setupCamera() {

  let input = try? AVCaptureDeviceInput(device: videoCaptureDevice)

  if self.captureSession.canAddInput(input) {
      self.captureSession.addInput(input)
  }

  self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

  if let videoPreviewLayer = self.previewLayer {
      videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
      videoPreviewLayer.frame = self.view.bounds
      view.layer.addSublayer(videoPreviewLayer)
  }

  let metadataOutput = AVCaptureMetadataOutput()
  if self.captureSession.canAddOutput(metadataOutput) {
      self.captureSession.addOutput(metadataOutput)

      metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
      metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]
  } else {
      print("Could not add metadata output")
  }
}

 override func viewWillAppear(_ animated: Bool) {
   super.viewWillAppear(animated)

   if (captureSession.isRunning == false) {
      captureSession.startRunning();
   }
}

override func viewWillDisappear(_ animated: Bool) {
  super.viewWillDisappear(animated)

  if (captureSession.isRunning == true) {
     captureSession.stopRunning();
  }
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
   // This is the delegate'smethod that is called when a code is readed
   for metadata in metadataObjects {
       let readableObject = metadata as! AVMetadataMachineReadableCodeObject
       let code = readableObject.stringValue


       self.dismiss(animated: true, completion: nil)
       self.delegate?.barcodeReaded(barcode: code!)
       print(code!)
   }
 }
}

My segue is just a simple drag to show, not programmatically. So I am a bit confused as to why it's crashing.

Here's the error:

Could not cast value of type 'BarCodeProj.ViewController' (0x1000361b0) to 'BarCodeProj.BarcodeViewController' (0x100035a78).


Solution

  • This is a case where the console error tells you everything you need to know. segue.destination is not a BarcodeReaderViewController so your attempt to cast it to one (with as!) is causing a catastrophic failure.

    First, check in your storyboard and make sure you set the type of the view controller properly (the one that you are transitioning to.)

    Do this by selecting the appropriate view controller in the storyboard and checking here:

    location where class name must be entered.