THE DEVELOPER EDITION / REVIEWED 26 OCT 2026

Cameras and scene accessories on iPhone Duo

Original summary of Apple's articles Choosing a camera by the direction it faces (AVKit) and Registering a camera capture accessory on iPhone Duo (AVFoundation), plus tech talks 111464 (multiple displays and scenes) and 111465 (camera). Checked against Apple's docs on 2026-10-21. Read this only for apps that capture photos or video, or that show content across both displays. Back to the main reference.

Availability: AVCaptureDeviceDirectionCoordinator, AVCaptureDeviceDescriptor, AVCaptureDeviceDirectionMap, the outer / inner ultra-wide device types, CameraCaptureAccessory, and UISceneAccessory.cameraCapture(...) are iOS 27.1 (final release in Xcode 27.1). sceneAccessory(content:), onAvailabilityChange(perform:), UISceneAccessoryRegistration, and registerSceneAccessory(_:) are 27.0. Guard with #available. Simulator has no camera: test capture on a device.

1. Which way a camera faces

Each display has its own front camera. Opening or closing the device moves your app to the other display, so a camera that faced the same way as your UI can now face the opposite way. AVCaptureDevice.Position says where a camera sits, not which way it points.

2. Following direction

@MainActor final class DirectionObserver {
    private var coordinator: AVCaptureDeviceDirectionCoordinator?
    func start(previewView: UIView) {
        coordinator = AVCaptureDeviceDirectionCoordinator(
            view: previewView,   // frame of reference only, it draws nothing
            deviceTypes: [.builtInOuterUltraWideCamera, .builtInInnerUltraWideCamera, .builtInDualWideCamera]
        ) { [weak self] directions in self?.didChange(directions) }
    }
}

3. Showing content on the outer display while capturing (scene accessory)

When the device is open and the rear camera is capturing, the outer display faces the subject. A camera capture accessory shows content there (a teleprompter script, a countdown, a framing preview).

// SwiftUI: register on the view that shows the capture interface.
CameraPreview().sceneAccessory {
    CameraCaptureAccessory(isEnabled: $isScriptEnabled) { ScriptView(model: script) }
        .onAvailabilityChange { showsScriptControls = $0 }
}
// UIKit: keep the registration; unregister rather than hide.
let accessory = UISceneAccessory.cameraCapture(sceneConfiguration: configuration, userInfo: script)
registration = registerSceneAccessory(accessory)   // UISceneAccessoryRegistration: isAvailable, isEnabled

4. Other multi-display and multi-window notes (talk 111464)