iphone-duo-adaptive-la…
Build layouts that adapt to the iPhone Duo fold using reserved regions, division and occlusion regions, displacement patterns,…
Build camera capture for iPhone Duo's two front cameras — the virtual front camera, the inner under-display and outer ultra-wide devices, AVCaptureDeviceDirectionCoordinator, the rotation coordinator, preview mirroring and video gravity, and dual-display capture. Use when an app
Claude Code
$ npx -y skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera --agent claude-code
Codex
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a codex -y
Cursor
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a cursor -y
Gemini CLI
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a gemini-cli -y
GitHub Copilot
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a github-copilot -y
OpenCode
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a opencode -y
Windsurf
$ npx skills add mirzaaghazadeh/iphone-duo-skills --skill iphone-duo-camera -a windsurf -y
name: iphone-duo-camera description: Build camera capture for iPhone Duo's two front cameras — the virtual front camera, the inner under-display and outer ultra-wide devices, AVCaptureDeviceDirectionCoordinator, the rotation coordinator, preview mirroring and video gravity, and dual-display capture. Use when an app captures photo or video and must handle the device opening, closing or flipping.
iPhone Duo is the first iPhone with **two front cameras**. Both are square sensors with an ultra-wide field of view: one on the outer display, and one beneath the inner display — the first under-display camera on iPhone.
That creates a problem no previous iPhone had. "Front" no longer means "pointing at the user."
Everything downstream follows from this choice.
Discover a front camera the ordinary way — an `AVCaptureDevice.DiscoverySession` requesting position `.front` with a Wide or Ultra Wide device type — and on iPhone Duo you resolve to a new **virtual front camera**. It switches between the two physical cameras by itself: inner camera when open, outer camera when closed.
It always uses the most relevant camera, and you write no switching code.
The cost is that it exposes only what **both** physical cameras can do:
If the app needs 4K, high frame rates, or any depth-based feature, this is not enough.
Address each physically, via the built-in **outer** ultra-wide and built-in **inner** ultra-wide device types:
| | Inner (under-display) | Outer | |---|---|---| | Max video | 1080p @ 60 fps | 4K @ 120 fps | | Depth | supported | supported |
Full capabilities, but now **you** must switch cameras when the user opens or closes the device. Which brings us to the hard part.
`AVCaptureDevice` has always had a fixed `position` — on iPhone, `.back` or `.front`. Both of iPhone Duo's front cameras report `.front`. That property describes where a camera sits **on the hardware**, and on a device whose displays can face opposite directions it no longer tells you where the camera **points relative to the person looking at your UI**.
Three situations make this concrete:
camera — a "front" camera facing *away* from them.
around to face them directly.
`AVCaptureDeviceDirectionCoordinator` (in **AVKit**) answers the real question: which cameras are forward-facing *right now*, relative to a given view. Build one from three things — your app's `UIView`, the device types to monitor, and a change handler — and it keeps you current as the device moves.
Because it is anchored to a view, it reports facing **relative to the display that view is on**. When the view is on the outer display, the outer front cameras are forward-facing and the rear cameras are backward-facing. Open the device, the view moves to the inner display, your handler fires, and now the inner front camera is forward-facing while the outer front *and* rear cameras are backward-facing.
**Driving both displays at once?** Create **one coordinator per view**. Each reports relative to its own display, so the same rear camera is forward-facing to the outer view's coordinator and backward-facing to the inner view's. That is correct, not contradictory — it is the whole point. (Dual-display camera UI comes from the scene accessories API; see `../iphone-duo-hinge-and-scenes/SKILL.md`.)
The coordinator is tied to a view, so it is **isolated to the main actor**. Your change handler must not call AVFoundation APIs directly.
It never hands you an `AVCaptureDevice`. The handler receives an **`AVCaptureDeviceDirectionMap`**, which sorts the tracked cameras into two arrays:
var forwardFacingDeviceDescriptors: [AVCaptureDeviceDescriptor] var backwardFacingDeviceDescriptors: [AVCaptureDeviceDescriptor]
The same map is also readable at any time from the coordinator's `deviceDirections` property, so you aren't limited to reacting inside the handler.
An **`AVCaptureDeviceDescriptor`** is a sendable stand-in for a capture device, carrying `uniqueID`, `localizedName`, `deviceType`, `mediaTypes` and `position`. Pass a descriptor to your camera actor and construct the `AVCaptureDevice` there. That is the intended path; don't try to smuggle a device across the boundary.
Note that both of these types live in **AVKit**, alongside the coordinator — not in AVFoundation, where you might reasonably go looking first.
Because you get *arrays* rather than a single device, your handler has to choose: typically the first forward-facing descriptor whose `deviceType` matches what you're streaming. Don't assume exactly one camera faces forward.
1. Reconfigure the `AVCaptureSession` to keep streaming from whichever camera is now forward-facing. 2. Re-evaluate **mirroring**. Mirroring should follow the *direction*, not the position: when a rear camera has become the forward-facing one, mirror the preview so it feels like a normal selfie view. 3. Apply any UI updates the camera change implies.
**Streaming the rear camera's full field of view on the inner display** leaves extra room around the preview. Two reasonable choices: offset the preview and group controls in the space left over, or let the preview fill the display. Control this with `videoGravity` on `AVCaptureVideoPreviewLayer`.
**Streaming an ultra-wide front camera**, exploit the square sensor — set `dynamicAspectRatio` on the `AVCaptureDevice` to pick a landscape aspect ratio that fills
Image © Apple Inc., from the iPhone Duo developer page, used for identification. Not affiliated with or endorsed by Apple. Agent skills for building iOS apps on iPhone Duo — Apple's first foldable iPhone, announced September 9, 2026.
Build layouts that adapt to the iPhone Duo fold using reserved regions, division and occlusion regions, displacement patterns,…
Adapt a Capacitor or Ionic app to iPhone Duo, Apple's first foldable iPhone — why the standard Device Posture and Viewport…
Review or design an iOS interface for iPhone Duo's poses — closed, open, book-folded, tabletop and tent — covering side-mounted…
Design and build two-pane experiences for iPhone Duo — the real pixel and point dimensions of each display and each half, the…
Adapt a Flutter app to iPhone Duo, Apple's first foldable iPhone — what MediaQuery gives you today, why displayFeatures does not…
Adapt a game to iPhone Duo — filling the screen across every device pose, orientation locking, aspect ratio versus letterboxing,…
Decompile Android APK, XAPK, JAR, and AAR files using jadx or Fernflower/Vineflower. Reverse engineer Android apps, extract HTTP…