Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2026 Audio & VideoPhotos & Camera

WWDC26 · 25 min · Audio & Video / Photos & Camera

Build a responsive camera app that launches quickly

Discover how to build a camera app that launches instantly so people never miss the perfect shot. Explore how to optimize the entire camera launch sequence — from app startup to first preview frame. Ensure your app has a polished camera experience by learning about new API’s that deliver faster launches, and best practices for smooth preview rendering and maintaining sustainable performance.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

Code shown on screen · 8 snippets

Automatic deferred start delegate swift · at 9:14 ↗
import AVFoundation

class DeferredStartDelegate: NSObject, AVCaptureSessionDeferredStartDelegate {
    func sessionWillRunDeferredStart(_ session: AVCaptureSession)
    {
        // This is called before deferred start begins for the deferred outputs
    }

    func sessionDidRunDeferredStart(_ session: AVCaptureSession)
    {
        // This is called after deferred start completes for all outputs
    }
}
Adopt automatic deferred start swift · at 9:46 ↗
import AVFoundation

let captureSession = AVCaptureSession()
captureSession.beginConfiguration()
captureSession.automaticallyRunsDeferredStart = true

let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer.isDeferredStartEnabled = false

let photoOutput = AVCapturePhotoOutput()
photoOutput.isDeferredStartEnabled = true
captureSession.addOutput(photoOutput)

captureSession.setDeferredStartDelegate(deferredStartDelegate, deferredStartDelegateCallbackQueue: sessionQueue)

captureSession.commitConfiguration()
captureSession.startRunning()
Adopt manual deferred start swift · at 11:30 ↗
import AVFoundation

let captureSession = AVCaptureSession()
captureSession.beginConfiguration()
captureSession.automaticallyRunsDeferredStart = false

let videoOutput = AVCaptureVideoDataOutput()
captureSession.addOutput(videoOutput)
videoOutput.isDeferredStartEnabled = false

let photoOutput = AVCapturePhotoOutput()
photoOutput.isDeferredStartEnabled = true
captureSession.addOutput(photoOutput)

captureSession.setDeferredStartDelegate(deferredStartDelegate, deferredStartDelegateCallbackQueue: sessionQueue)

captureSession.commitConfiguration()
captureSession.startRunning()
Manage runDeferredStartWhenNeeded swift · at 11:53 ↗
import AVFoundation
import QuartzCore

private var firstFramePresented = false
guard let drawable = layer.nextDrawable()
if (!firstFramePresented) {
    drawable.addPresentedHandler({ drawable in
        // Set up postponed UI elements
        captureSession.runDeferredStartWhenNeeded()
    })
    firstFramePresented = true
}
Enable responsive capture swift · at 14:07 ↗
import AVFoundation

func configurePhotoOutput(for session: AVCaptureSession, device: AVCaptureDevice) {
    let photoOutput = AVCapturePhotoOutput()

    guard session.canAddOutput(photoOutput) else { return }
    session.addOutput(photoOutput)

    photoOutput.maxPhotoQualityPrioritization = .quality
    // Responsive capture lets the photo output capture immediately
    photoOutput.isResponsiveCaptureEnabled = photoOutput.isResponsiveCaptureSupported
}
Monitor for system pressure swift · at 20:16 ↗
import AVFoundation

let captureSession = AVCaptureSession()
let device = activeVideoInput?.device
captureSession.beginConfiguration()
// ...
captureSession.commitConfiguration()

guard captureSession.hardwareCost <= 1.0 else {
    print("hardwareCost \(captureSession.hardwareCost) — cannot start session. Reconfiguring.")
    setupLowCostConfiguration()
}

captureSession.startRunning()
let systemPressureObserver = device?.observe(\.systemPressureState,
                                               options: [.initial, .new],
                                               changeHandler: { /* Handle state change */ })
Manage pro video storage swift · at 22:17 ↗
import AVFoundation

func configureProVideoStorage() {
    guard AVProVideoStorage.isSupported else { return }
    let storage = AVProVideoStorage.shared
    guard storage.remainingCapacity != 0 else {
        storage.openSettings()
        return
    }
}
Adopt AVProVideoStorage for deterministic file write speeds swift · at 22:43 ↗
import AVFoundation

guard AVProVideoStorage.isSupported else { return }
guard let pvs = AVProVideoStorage.shared else { return }

// Configure and set up AVCaptureSession, AVCaptureConnections and format
// ...
let movieOutput = AVCaptureMovieFileOutput()

guard movieOutput.isProVideoStorageSupported else { return }
guard !pvs.isBusy else { return }

let movieFileURL = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString)
            .appendingPathExtension("mov")

movieOutput.usesProVideoStorage = true // Also available with AVAssetWriter
movieOutput.startRecording(to: movieFileURL, recordingDelegate: delegate)

Resources