Repository navigation
Fix: manual exposure crashed the app on iPhone 18 Pro - #272
Merged
Merged
Conversation
…18 Pro setExposureModeCustom(duration:iso:) locks the aperture too, and the iPhone 18 Pro refuses aperture + shutter + ISO all locked: the call raised an NSInvalidArgumentException and killed the app. The format now says which custom mode it takes (iOS 27 supportsExposureModeCustom(lensAperture:...)): all locked keeps the old call, shutter + ISO locked with auto aperture uses setExposureModeCustom(lensAperture: .auto, ...), and neither reports no Manual so the director offers bias only. The iOS 27 calls sit behind #if compiler(>=6.4) so the Xcode 26.2 CI build compiles; that build keeps the old behavior. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fix needs the iOS 27 SDK. Build, Catalyst and the App Store release move from macos-26 / Xcode 26.2 to GitHub's xcode-27 image with Xcode 27.1 (a release build, which App Store Connect accepts), tests on the iOS 27.0 iPhone 17 simulator. Compilation caches are keyed per Xcode version. With the SDK guaranteed, the #if compiler guard goes: a missing API now fails the build instead of silently dropping the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
📊 Test Coverage Report✅ 784/809 tests passed · ⏭️ 25 skipped
🎥 Capture & session core
📁 Full report — 103 files
Generated from |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
If you set manual exposure from the remote on an iPhone 18 Pro, the camera phone's app crashed. This fixes it.
What happened, in plain words
Think of the camera as a room with one window. Three things decide how bright the photo is: how long the window stays open (shutter), how wide it opens (aperture), and how sensitive the eye inside is (ISO).
On every iPhone before the 18 Pro, the window is always the same size. So when you went manual, the app told the phone "freeze all three", and that was fine, because one of them never moved anyway.
The 18 Pro has a window that can change size. Apple doesn't let you freeze all three at once on it. We asked anyway, and instead of politely saying no, the app crashed in the middle of the shoot.
What we do now
Before going manual, the app asks the phone what it's willing to do.
Nobody gets a crash.
The build server moves to Xcode 27
The fix uses tools that only exist in Apple's newest developer kit, so this PR also moves our build server to it. Tests, the Mac build and the App Store release now run on Xcode 27.1, a release version that App Store Connect accepts. Before, they ran on Xcode 26.2.
GitHub still calls its Xcode 27 machines a "preview", so CI jobs may wait in line a bit longer than they used to.
Tested
For reviewers: the technical version
setExposureModeCustom(duration:iso:)is, per Apple's header, "equivalent to passingAVCaptureLensApertureCurrent", so it locks aperture too. On the 18 Pro that raisedNSInvalidArgumentException("Unsupported combination of auto/locked parameters (lensAperture locked, duration locked, ISO locked)"), which Swift can't catch.CaptureEngine.manualAperture(for:)asks the active format via iOS 27supportsExposureModeCustom(lensAperture:duration:iso:): all locked →.locked(old call), auto aperture with shutter + ISO locked →.auto(setExposureModeCustom(lensAperture: .autoLensAperture, …)), neither → nil (no Manual).ExposureFacts.supportsCustom, the reportedsupportsManual, and the lens-hop choice.#available(iOS 27.0, macCatalyst 27.0, *). CI and release run on GitHub'sxcode-27image with Xcode 27.1, tests on the iOS 27.0 iPhone 17 simulator, and compilation caches are keyed per Xcode version.testExposureProbeAppliesAndReportsTruth: ISO tolerance ±1 → 1%, because the 18 Pro lands 400 as 398.77.ISO is really a gain applied to the sensor's signal, not the eye getting more sensitive, and the window size is the f-number (focal length over opening diameter). The picture holds for the point here: the 18 Pro has one more moving part, and it won't let you freeze all of them at once.
🤖 Generated with Claude Code