-
Crea una app de cámara con una gran capacidad de respuesta que se inicie rápidamente
Descubre cómo crear una app de cámara que se abra al instante para que las personas nunca se pierdan la foto perfecta. Descubre cómo optimizar toda la secuencia de inicio de la cámara, desde que se abre la app hasta que aparece el primer fotograma de vista previa. Asegúrate de que tu app ofrezca una experiencia de cámara optimizada: obtén información sobre las nuevas API que permiten un inicio más rápido, así como las mejores prácticas para una visualización fluida de las vistas previas y para mantener un rendimiento constante.
Capítulos
- 0:00 - Introducción
- 2:02 - Inicio rápido
- 6:52 - Adopta el inicio diferido
- 15:06 - Vista previa fija
- 18:04 - Rendimiento sostenido
- 21:14 - Escritura de archivos deterministas
Recursos
- Build a responsive camera app that launches quickly
- Performance and metrics
- AVCam: Building a camera app
Videos relacionados
WWDC26
WWDC23
-
Buscar este video…
-
-
9:14 - Automatic deferred start delegate
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 } } -
9:46 - Adopt automatic deferred start
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() -
11:30 - Adopt manual deferred start
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() -
11:53 - Manage runDeferredStartWhenNeeded
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 } -
14:07 - Enable responsive capture
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 } -
20:16 - Monitor for system pressure
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 */ }) -
22:17 - Manage pro video storage
import AVFoundation func configureProVideoStorage() { guard AVProVideoStorage.isSupported else { return } let storage = AVProVideoStorage.shared guard storage.remainingCapacity != 0 else { storage.openSettings() return } } -
22:43 - Adopt AVProVideoStorage for deterministic file write speeds
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)
-