We start by setting up the project to take photos. We start by disabling rotation, which is typical of a camera app. We then add the appropriate Info.plist entry so that we can inform the user why we need camera access. We organize the view controller intro sections to keep things tidy as we add code to the project. Finally we setup the camera capture session, which is the first step to capturing video from the camera.
Initial View Controller class CaptureViewController: UIViewController { // MARK: - View Lifecycle override func viewDidLoad() { super.viewDidLoad() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if AVCaptureDevice.authorizationStatus(for: .video) == .authorized { setupCaptureSession() } else { // prompt the user... } } // MARK: - Rotation override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return [.portrait] } private func setupCaptureSession() { // ... } } Finding the Capture Device // MARK: - Camera Capture private func findCamera() -> AVCaptureDevice? { let deviceTypes: [AVCaptureDevice.DeviceType] = [ .builtInDualCamera, .builtInTelephotoCamera, .builtInWideAngleCamera ] let discovery = AVCaptureDevice.DiscoverySession(deviceTypes: deviceTypes, mediaType: .video, position: .back) return discovery.devices.first } Setting up the Capture Session First, we add a lazy property to return a new instance. // MARK: - Properties lazy var captureSession: AVCaptureSession = { let session = AVCaptureSession() session.sessionPreset = .high return session }() Then we can add inputs to it... private func setupCaptureSession() { // if we've added inputs already, don't do it again... guard captureSession.inputs.isEmpty else { return } // make sure we have a camera to attach to guard let camera = findCamera() else { print("No camera found") return } do { // add the input let cameraInput = try AVCaptureDeviceInput(device: camera) captureSession.addInput(cameraInput) } catch let e { print("Error creating capture session: \(e)") return } }