How to switch camera? - Implementing a camera flip button

What I have figured out is that in order to switch cameras it is necessary to end the AVCaptureSession and create a new AVCapture session so you can add another AVCaptureDevice? Please correct me if I’m wrong!

How I am switching the camera right now is still really buggy, it only switches twice and the code is really long for something that seems so simple!

fileprivate var currentCameraPosition: CurrentCameraPosition?

enum CurrentCameraPosition
{
    case front
    case back
}

fileprivate func switchCamera()
{
    if session.isRunning
    {
        session.stopRunning()
        session.removeInput(videoDeviceInput)
    }
    
    session.beginConfiguration()
    session.sessionPreset = AVCaptureSessionPresetPhoto
    
    if currentCameraPosition == .back
    {
        do{
            let videoDeviceFrontCamera = AVCaptureDevice.defaultDevice(withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
            let videoDeviceInput = try AVCaptureDeviceInput(device: videoDeviceFrontCamera)
            
            if session.canAddInput(videoDeviceInput)
            {
                session.addInput(videoDeviceInput)
                self.currentCameraPosition = CurrentCameraPosition.front
                self.videoDeviceInput = videoDeviceInput
                DispatchQueue.main.async {
                    self.cameraPreviewView.cameraPreviewLayer.connection.videoOrientation = .portrait
                }
            }
            else
            {
                print("Could not switch camera")
                return
            }
        }
        catch
        {
            print("Couldn't create video device input: \(error)")
            return
        }
    }
    else if currentCameraPosition == .front
    {
        do{
            let videoDeviceFrontCamera = AVCaptureDevice.defaultDevice(withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.back)
            let videoDeviceInput = try AVCaptureDeviceInput(device: videoDeviceFrontCamera)
            
            if session.canAddInput(videoDeviceInput)
            {
                session.addInput(videoDeviceInput)
                self.currentCameraPosition = CurrentCameraPosition.front
                self.videoDeviceInput = videoDeviceInput
                DispatchQueue.main.async {
                    self.cameraPreviewView.cameraPreviewLayer.connection.videoOrientation = .portrait
                }
            }
            else
            {
                print("Could not switch camera")
                return
            }
        }
        catch
        {
            print("Couldn't create video device input: \(error)")
            return
        }
    }
    session.commitConfiguration()
    
    sessionQueue.async {
        self.session.startRunning()
    }
}

It looks like you have a cut & paste error there - should self.currentCameraPosition = CurrentCameraPosition.front appear in both code paths?

Because your code paths have so much in common you should maybe extract out the common part and put it in a function that is called with an argument for front or back…

should self.currentCameraPosition = CurrentCameraPosition.front appear in both code paths? This was the simple overlooked trick that did it! just had to set variable to the other position whenever switched!

And the method did definitely do the trick on shortening code, originally was just curious if there was a better way than having to call a method that runs through all that code again rather then just switching the position.

I guess you can make incremental changes and experiment to see exactly how much setup is required when switching. Glad the suggestion helped.