0

I'm creating an app that users AVFoundation to record a video. I have a Login View Contoller which leads to a View Controller (user can see their profile details here) which leads to a Data Collection View Controller (this is where the video camera is presented). All works fine but when I click on a back button to go back to the View Controller, and then click 'start data collection' to go back into the video camera a 2nd time, the app crashes.

Crash info:

2018-08-11 11:39:51.861569+0100 LiopaDatacapture-iOS[6343:1642808] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[AVCaptureMetadataOutput setMetadataObjectTypes:] Unsupported type found - use -availableMetadataObjectTypes' *** First throw call stack: (0x1842e6d8c 0x1834a05ec 0x189e54b44 0x10128f4fc 0x1012989a4 0x101298ca4 0x18df01e64 0x18df01a50 0x18eaa4fd8 0x18e12b398 0x18e12a25c 0x18e3a33a0 0x18e0e13e4 0x18e1297bc 0x18e129654 0x18e3a6350 0x18e734d24 0x18e881af4 0x18e8819a0 0x18e39a49c 0x101297f5c 0x18e05564c 0x18e176870 0x18e05b700 0x18e1911a8 0x18e0d89e0 0x18e0cd890 0x18e0cc1d0 0x18e8add1c 0x18e8b02c8 0x18e8a9368 0x18428f404 0x18428ec2c 0x18428c79c 0x1841acda8 0x186192020 0x18e1cc758 0x101284a90 0x183c3dfc0) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

I'm using AVCaptureMetadataOutput to detect faces. This code is in my SessionHandler class where the video camera is being set up.

// define metadata
        let metaOutput = AVCaptureMetadataOutput()

        if cameraSession.canAddOutput(metaOutput) {
            metaOutput.setMetadataObjectsDelegate(self, queue: faceQueue)
            cameraSession.addOutput(metaOutput)
            print("metaoutput added")
        }

        // set metadata to look for faces
        metaOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.face]

In my DataCaptureViewController.swift file this is where I load the video camera-

 override func viewDidLoad() {
    super.viewDidLoad()

    sessionHandler.setupCamera()
    audioRecorder.setUpAudioSession()

    createObservers()

    let layer = sessionHandler.layer
    layer.frame = previewView.bounds
    previewView.layer.addSublayer(layer)
    view.layoutIfNeeded()

    jsonSentence.text = "Press start button to get phrase"
    startButton.setTitle("Start", for: .normal)

}

I've played around a bit trying viewDidAppear and viewWillAppear but I'm new to swift and don't think I fully understand what they do or if this is what's causing the problem.

The SessionHandler class variables need to be shared with an Objective-C class so I've created a shared instance of it to be used throughout the app.

static let sharedSession = SessionHandler()

It's hard to know what code is useful to share but if you need any more info I'm happy to provide it.

Hardy143
  • 577
  • 4
  • 13

1 Answers1

0

The answer seemed pretty straightforward in the end, sorry for the big question!

It was because the metadataObjectTypes was empty when the DataCaptureViewController was reloaded. So I created a viewDidAppear method and set the metadataObjectTypes to face in there.

override func viewDidLoad() {
    super.viewDidLoad()
    sessionHandler.setupCamera()
    audioRecorder.setUpAudioSession()

    createObservers()

    let layer = sessionHandler.layer
    layer.frame = previewView.bounds
    previewView.layer.addSublayer(layer)
    view.layoutIfNeeded()

    jsonSentence.text = "Press start button to get phrase"
    startButton.setTitle("Start", for: .normal)


}

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

    sessionHandler.metaOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.face]
}

The app seems to be working now. If I've done this incorrectly though feel free to correct!

Hardy143
  • 577
  • 4
  • 13