AVCapturePhotoCaptureDelegate methods aren't being called every time

Viewed 517

I'm building a custom camera, and I'm having flakey results. When I attempt to capture an image, I'm sometimes not receiving the expected delegate callbacks. For example, here are my delegate methods:

func photoOutput(_ output: AVCapturePhotoOutput, willBeginCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
    print("will begin")
}

func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
    print("will capture")
}

func photoOutput(_ output: AVCapturePhotoOutput, didCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
    print("did capture")
}

func photoOutput(_ output: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
    print("finished capture")
}

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    print("finish process")
}

I have a button that triggers the following method:

func capture() {
    print("capture called")
    let settings = AVCapturePhotoSettings()
    captureOutput.capturePhoto(with: settings, delegate: self)
}

Every time this method is called, I expect the following output in the console:

capture called

will begin
will capture
did capture
finish process
finished capture
image set

However, it seems like a 50/50 chance that I only get the following output:

capture called
did capture

What's going on here?

2 Answers

I was experiencing the same issue, but it was because I was calling stopRunning() on the capture session right after calling capturePhoto(with: settings, delegate: self)

I ended up removing the stopRunning() call and it got fixed.

func takePicture() {
        let settings = AVCapturePhotoSettings()    

        imageOutput?.capturePhoto(with: settings, delegate: self)

        videoPreviewLayer?.connection?.isEnabled = false // to freeze the image
}

However, take into account you need to call stopRunning() at some point (for example on viewWillDisappear)

I found this example from Apple that really helped me https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/avcam_building_a_camera_app

Related