The iPhone 17, iPhone Air, and iPhone 17 Pro feature a square-sensor ultra-wide front camera with a 95° field of view. iOS 26 exposes new APIs ā dynamic aspect ratio and a smart framing monitor ā so apps can deliver auto-zoom, auto-rotate, and Center Stage tracking for selfies, recordings, and video calls.
⢠Dynamic aspect ratio lets you switch between portrait, landscape, and square crops seamlessly without rebuilding the capture session ā enabling one-tap Tap-to-Rotate UX.
⢠The AVCaptureSmartFramingMonitor delivers real-time framing recommendations (aspect ratio + zoom factor) based on face/gaze detection, so group selfies are always well-framed automatically.
⢠A new low-latency stabilization mode and built-in sensor orientation compensation mean video calls and recordings just work correctly on the new sensor without extra rotation math.
Demonstrates setting up the Center Stage front camera with dynamic aspect ratio and observing the AVCaptureSmartFramingMonitor to automatically apply face-aware zoom and rotation recommendations.
import AVFoundation
import SwiftUI
import Combine
// MARK: - Camera Manager
@Observable
final class CenterStageCameraManager: NSObject {
private let session = AVCaptureSession()
private var device: AVCaptureDevice?
private var smartFramingObservation: NSKeyValueObservation?
var previewLayer: AVCaptureVideoPreviewLayer?
var currentAspectRatio: AVCaptureDevice.AspectRatio = .init(width: 4, height: 3)
func configure() throws {
// 1. Find the Center Stage ultra-wide front camera
let discovery = AVCaptureDevice.DiscoverySession(
deviceTypes: [.builtInUltraWideCamera],
mediaType: .video,
position: .front
)
guard let ultraWideFront = discovery.devices.first else {
throw CameraError.deviceNotFound
}
self.device = ultraWideFront
// 2. Find a format supporting dynamic aspect ratio (4032 for smart framing)
guard let format = ultraWideFront.formats.first(where: { format in
format.supportedDynamicAspectRatios.contains(
AVCaptureDevice.AspectRatio(width: 4, height: 3)
) && format.isSmartFramingSupported
}) else {
throw CameraError.formatNotFound
}
// 3. Configure the device
try ultraWideFront.lockForConfiguration()
ultraWideFront.activeFormat = format
ultraWideFront.dynamicAspectRatio = AVCaptureDevice.AspectRatio(width: 4, height: 3)
ultraWideFront.unlockForConfiguration()
// 4. Build the capture session
session.beginConfiguration()
let input = try AVCaptureDeviceInput(device: ultraWideFront)
if session.canAddInput(input) { session.addInput(input) }
let photoOutput = AVCapturePhotoOutput()
if session.canAddOutput(photoOutput) { session.addOutput(photoOutput) }
session.commitConfiguration()
// 5. Preview layer
let layer = AVCaptureVideoPreviewLayer(session: session)
layer.videoGravity = .resizeAspectFill
self.previewLayer = layer
// 6. Start smart framing monitor
startSmartFramingMonitor(on: ultraWideFront)
session.startRunning()
}
private func startSmartFramingMonitor(on device: AVCaptureDevice) {
let monitor = device.smartFramingMonitor
// Enable all supported framings (aspect ratios + zoom levels)
monitor.enabledFramings = monitor.supportedFramings
monitor.startMonitoring()
// KVO observe the recommended framing
smartFramingObservation = monitor.observe(
\.recommendedFraming,
options: [.new]
) { [weak self, weak device] _, change in
guard let self, let device,
let recommendation = change.newValue as? AVCaptureSmartFramingMonitor.Framing
else { return }
self.applyRecommendation(recommendation, to: device)
}
}
private func applyRecommendation(
_ framing: AVCaptureSmartFramingMonitor.Framing,
to device: AVCaptureDevice
) {
do {
try device.lockForConfiguration()
// Apply aspect ratio first, then zoom for smooth transition
device.dynamicAspectRatio = framing.aspectRatio
device.videoZoomFactor = framing.zoomFactor
device.unlockForConfiguration()
currentAspectRatio = framing.aspectRatio
} catch {
print("Failed to apply framing recommendation: \(error)")
}
}
func stopMonitoring() {
smartFramingObservation?.invalidate()
smartFramingObservation = nil
device?.smartFramingMonitor.stopMonitoring()
}
enum CameraError: Error {
case deviceNotFound
case formatNotFound
}
}
// MARK: - SwiftUI Preview Wrapper
struct CameraPreviewView: UIViewRepresentable {
let previewLayer: AVCaptureVideoPreviewLayer
func makeUIView(context: Context) -> UIView {
let view = UIView()
view.layer.addSublayer(previewLayer)
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
previewLayer.frame = uiView.bounds
}
}
// MARK: - Content View
struct CenterStageDemoView: View {
@State private var camera = CenterStageCameraManager()
@State private var errorMessage: String?
var body: some View {
ZStack {
if let layer = camera.previewLayer {
CameraPreviewView(previewLayer: layer)
.ignoresSafeArea()
}
VStack {
Spacer()
Text("Auto-Framing Active")
.font(.caption)
.padding(8)
.background(.ultraThinMaterial, in: Capsule())
.padding(.bottom, 40)
}
}
.task {
do {
try camera.configure()
} catch {
errorMessage = error.localizedDescription
}
}
.onDisappear { camera.stopMonitoring() }
.alert("Camera Error", isPresented: .constant(errorMessage != nil)) {
Button("OK") { errorMessage = nil }
} message: {
Text(errorMessage ?? "")
}
}
}iOS 27 adds sectioned queries, codable model attributes, ResultsObserver for non-SwiftUI change observation, and HistoryObserver for reacting to persistent history changes in SwiftData.
USDKit is a new first-party Swift framework introduced in iOS/macOS 27 that brings native USD scene creation, composition, modification, and export capabilities to Apple platform apps, with deep RealityKit and Spatial Preview integration.
LiveCommunicationKit is the modern replacement for CXProvider that delivers rich, native conversation UIs integrated with the Lock Screen, Dynamic Island, Phone app Recents, and Siri. It provides a unified lifecycle model for audio and video conversations with a single delegate-driven action pipeline.
Changing dynamicAspectRatio during an active AVCaptureMovieFileOutput recording will automatically stop the recording ā you must restart it. The smartFramingMonitor must be explicitly started and its KVO observation removed when the user disables auto-framing. Sensor orientation compensation is on by default but should be tested with it off for performance-sensitive paths. Center Stage for video calls is enabled per-process, not per-camera.
Requires iPhone 17, iPhone Air, or iPhone 17 Pro. APIs targeting the square sensor only apply to AVCaptureDevice with .builtInUltraWideCamera at .front position. Smart framing monitor only provides recommendations when using the 4032 photo format. RAW and ProRAW captures are exempt from sensor orientation compensation.
The NowPlaying framework introduces a first-class Swift API for surfacing app media in system-wide now-playing surfaces ā Lock Screen, Control Center, Dynamic Island, StandBy, CarPlay, Apple Watch, and Apple TV ā via a declarative MediaSessionRepresentable protocol. It also supports remote media sessions (for controlling external speakers/TVs) and Media Sharing Extensions for routing media to third-party devices.