← All posts

Product update4 min read

The app said the iPhone was too old. The build was.

Three TestFlight builds shipped without camera vision because of a toolchain change, and the app told people on iOS 27 their phone was the problem. How the message was made honest.

A feature went missing, and the app blamed the phone

ICIDO can answer "what do you see?" by describing the camera view. Since the bundled 370 MB model was removed, that answer comes from Apple Intelligence on iPhones that support it, and from nothing on iPhones that do not (812a911). The code path for it is guarded at compile time by #if canImport(USDKit), which is false whenever the app is compiled against an SDK older than iOS 27 (812a911).

A compile-time guard has one property worth remembering: it decides based on the machine that built the app, not the phone that runs it.

Between builds 249 and 250, Apple stopped accepting uploads built with the iOS 27 beta SDK. Build 250 therefore went out from Xcode 26.6, and so did 251 and 252 (fcef265, 812a911). On that SDK the guard is false. Camera vision was absent from those three builds for everyone, including people on iOS 27 who had it working in build 249 (fcef265).

That much was a toolchain accident. What the app said about it was not.

"Needs iOS 27 or later"

Everywhere camera vision was missing, the app showed one line: "Needs iOS 27 or later." It showed that line to people already running iOS 27 (812a911).

Spoken aloud, the message went further. Both voice hosts answered a camera question with: "This iPhone can't describe what the camera sees. That needs a newer iPhone with Apple Intelligence. Everything else still works." (812a911)

The commit that fixed this describes the problem in one sentence. Told to someone who cannot see the screen, that is close to advice to go and buy a phone, for something we did to the build (812a911).

The message was not vague or unhelpful. It was specific, confident, and wrong in a way that pointed at the user's hardware. For someone who relies on the spoken answer, it is the only account of the situation they get, and it told them the fault was theirs.

Two different questions, one honest answer each

The app used to have one notion: can this device run camera vision, or not. It now has two (812a911).

SystemVision.missingFromThisBuild is true when the build itself was compiled without camera vision, whatever the phone is capable of. The existing check still answers the other question, whether this iPhone can run it. Both the Settings line and the spoken fallback now say which of the two is true (812a911).

So the current wording, when the build is the problem, is: "This version of ICIDO was built without camera descriptions. An update will bring them back. Everything else still works." When the phone is the problem, the old sentence about needing a newer iPhone with Apple Intelligence stays, because in that case it is true (812a911).

Settings makes the same distinction. It shows the reason in place of the on/off switch, so someone on iOS 27 who simply has not switched Apple Intelligence on learns what to do about it, rather than being told their iPhone is too old (812a911).

Say it once

The spoken sentence used to live in two places. ScanVoiceHost and NavigationVoiceHost each carried their own copy of the same words. The commit is blunt about why that matters: it is how a correction gets made once and missed once (812a911).

The text now sits in one place, and both hosts read from it. Whatever is said to someone asking the camera a question during a scan is, by construction, what is said to them while navigating.

The warning that understated what was missing

There is a compiler warning that fires when ICIDO is built against a pre-27 SDK. After the bundled model was removed, that warning still said camera vision would "use the bundled SmolVLM only". There was no SmolVLM any more. On a pre-27 toolchain camera vision is absent outright, and the warning now says so (1c50918).

The reasoning in that commit is the same as for the user-facing message, pointed at the developer instead: a warning that understates what a build is missing is worse than no warning (1c50918).

Documentation that described deleted machinery

The same pass cleared out comments written for the two-model design and never updated when one model left (812a911):

  • The system vision file's header still carried a comparison table of the bundled model against Apple's, and ended with the instruction that neither path may become the only one. It is the only path.
  • The preferences said turning the switch off "sends iOS 27 users back to the downloadable model". There is no downloadable model; off now means no camera vision at all.
  • The pre-warm routine claimed to load model sessions costing seconds and hundreds of megabytes. It hands Apple's model some instructions.
  • The release routine claimed to drop roughly 400 MB of resident memory. It cancels a task.

None of these changed behaviour. They changed what the next person reading the code would believe, which is the same class of problem as the message on the screen: a confident statement about the state of things that stopped being true when something was deleted.

Restored, and checked

Build 253 went out with the corrected messages (1385051). Build 254 was the first upload from an iOS 27 toolchain since 249: the ship script's SDK guard passed without an override, the pre-27 warning stayed silent, and the shipped binary reports SDK 27.0 (3a2d855). The tooling that still pointed at a deleted beta Xcode now points at the release candidate (bc018f7).

Camera vision is back for the phones that can run it. For the phones that cannot, nothing else depends on it: every map question and every route work with no model at all (812a911). Camera frames are processed on the device in real time and are not recorded or stored (privacy policy).

Scanning requires the LiDAR sensor, on iPhone 12 Pro and later Pro models. The work here shipped in TestFlight builds.

Related reading