WWDC.ai

Build a great camera experience for iPhone Duo

Use iPhone Duo's virtual and individual front cameras, direction coordination, preview layout, aspect ratio, and rotation APIs for polished capture apps.

Watch on Apple Developer

TL;DR

  • iPhone Duo has inner and outer ultrawide front cameras; the Virtual Front Camera discovered with position .front automatically switches between them as the device opens or closes.
  • Use individual camera device types when you need each sensor's full capabilities: outer up to 4K/120fps, inner up to 1080p/60fps, and depth only through individual cameras.
  • Adopt AVCaptureDeviceDirectionCoordinator when selecting individual cameras so the app can react to cameras becoming forward- or backward-facing relative to a specific UIView.
  • Polish previews with AVCaptureVideoPreviewLayer.videoGravity, AVCaptureDevice.dynamicAspectRatio, AVCaptureDeviceRotationCoordinator, and by disabling camera sensor orientation compensation after adopting rotation coordination.

Camera model on iPhone Duo

iPhone Duo introduces two front cameras: an outer ultrawide camera on the outside display and an inner ultrawide under-display camera. Both use square sensors with an ultrawide field of view.

Existing AVFoundation discovery patterns continue to work. Apps that discover a front wide or ultrawide camera using AVCaptureDeviceDiscoverySession with position .front get the new Virtual Front Camera on iPhone Duo.

  • The Virtual Front Camera automatically uses the inner front camera when the device is open and the outer front camera when closed.
  • It is the simplest choice when an app does not need to manage camera switching itself.
  • Because it abstracts over both physical front cameras, it exposes only capabilities common to both.

Virtual camera vs. individual cameras

For more control, access the physical front cameras using their individual device types: .builtInOuterUltraWideCamera and .builtInInnerUltraWideCamera. This exposes each camera's full capabilities but makes the app responsible for switching as the device opens, closes, or moves between displays.

  • Inner ultrawide front camera: 1080p video, up to 60 fps.
  • Outer ultrawide front camera: up to 4K video and 120 fps.
  • Virtual Front Camera: maximum 1080p and 60 fps because it only exposes shared capabilities.
  • Depth is supported only when accessing the individual cameras, not through the Virtual Front Camera.

Track camera direction relative to your UI

AVCaptureDevice.position still reports .front for both front cameras, but on iPhone Duo a front camera is not necessarily facing the person using the current display. Displays can face opposite directions, and the same physical camera can become forward-facing or backward-facing as the device opens, closes, or flips.

Use AVCaptureDeviceDirectionCoordinator to monitor which cameras are forward-facing relative to a specific UIView. The coordinator needs the view, the device types to monitor, and a change handler.

  • When a view is on the outer display, outer front cameras are forward-facing and rear cameras are backward-facing.
  • When the UI moves to the inner display after opening, the inner front camera becomes forward-facing and outer front/rear cameras are reported accordingly.
  • If an app uses both displays at once, create a separate direction coordinator for each display's UIView; direction is relative to that view.
  • Camera apps can use SceneAccessories for both-display experiences; see the related iPhone Duo multiple displays and scenes session.

Initialize a direction coordinator

Create a coordinator for the view whose display-relative camera direction matters, and respond to direction changes in the handler.

directionCoordinator = AVCaptureDeviceDirectionCoordinator(
    view: view,
    deviceTypes: [
        .builtInOuterUltraWideCamera,
        .builtInInnerUltraWideCamera,
        .builtInDualWideCamera,
    ],
    changeHandler: { [weak self] map in
        self?.updateCameraSession(map)
    }
)

AVCaptureDevice position is not enough on iPhone Duo

Both front cameras report .front, so use direction coordination when you need to know which camera faces the active UI.

enum AVCaptureDevicePosition: Int {
    case unspecified
    case back
    case front
}

extension AVCaptureDevice {
    // ...
    var position: AVCaptureDevicePosition { get }
}

Handle direction changes safely

The direction coordinator is tied to a UIView, so it is main-actor isolated. Its change handler should not use AVFoundation APIs directly. Instead, it provides AVCaptureDeviceDescriptor, a main-actor-safe, sendable representation with enough information to create an AVCaptureDevice on a camera actor or other AVFoundation execution context.

When the handler fires, reconfigure the AVCaptureSession to keep streaming from the forward-facing camera, update preview mirroring decisions, and adjust any UI that depends on camera direction.

  • Mirror the preview when the rear camera is forward-facing to preserve a natural selfie-style experience.
  • Pass device descriptors out of the main-actor handler rather than passing or creating AVCaptureDevice instances there.
  • The session points to Apple documentation articles for choosing a camera by direction and supporting device rotation.

Polish preview layout, aspect ratio, and rotation

The rear camera's full field of view may leave extra space around the preview on the inner display. Apps can either offset the preview to leave room for controls or make the preview fill the display, depending on the capture experience.

Use AVCaptureVideoPreviewLayer.videoGravity to control how video fits inside layer bounds. When streaming from the ultrawide front cameras, use the square sensor with AVCaptureDevice.dynamicAspectRatio to select a landscape aspect ratio for the inner display.

Adopt AVCaptureDeviceRotationCoordinator so previews and photos remain upright. On iPhone Duo it updates when the app moves between displays. After adopting it, disable camera sensor orientation compensation on AVCapturePhotoOutput to improve performance; this compensation is enabled on all iPhone Duo front cameras.

  • Use the iOS 27.1 SDK to take full advantage of iPhone Duo camera behavior.
  • Test open, closed, flipped, and multi-display configurations to validate camera selection, mirroring, preview placement, and rotation.

Configure preview layout

Use videoGravity to decide how the camera image is laid out within the preview layer bounds.

class AVCaptureVideoPreviewLayer {
    // ...

    var videoGravity: AVLayerVideoGravity { get set }
}

Use a dynamic aspect ratio and disable compensation after rotation coordination

Use dynamicAspectRatio for display-filling front camera previews, and disable sensor orientation compensation after adopting AVCaptureDeviceRotationCoordinator.

class AVCaptureDevice {
    // ...

    var dynamicAspectRatio: AVCaptureDevice.AspectRatio? { get }
}

// Disable for improved performance
class AVCapturePhotoOutput: AVCaptureOutput {
    // ...

    var isCameraSensorOrientationCompensationEnabled: Bool { get set }
}
Unofficial, not associated with Apple. Made with ❤️ by

On this page

Ask AI