Fix the App Store Connect upload rejections: MediaPipe bundle versions and the DAT URL scheme - #306
Conversation
…sions and the DAT URL scheme
An upload of 2026.8 was rejected on five counts. Three are the same root cause, one is
a build-machine choice, one is a real bug that has been in every build we have shipped.
**MediaPipe frameworks have no version keys.** Google ships MediaPipeTasksCommon and
MediaPipeTasksVision with neither CFBundleVersion nor CFBundleShortVersionString, and
the fetch script only downloaded and moved them, so App Store Connect rejected both
bundles ("is invalid. The Info.plist file is missing the required key"). Every archive
since MediaPipe was vendored would have failed the same way. The script now stamps the
pinned version into every slice with `plutil -replace`, which adds the key when absent
and so is idempotent. It also runs on the already-fetched path, so existing checkouts
and warm CI caches repair themselves without a 1.2 GB re-download — and because
ci_scripts/ci_post_clone.sh calls the same script, Xcode Cloud is covered.
Audited the other five embedded frameworks while here: MWDAT x3, WebRTC and onnxruntime
all carry both keys, so this is the whole of it.
**The DAT URL scheme was a hardcoded placeholder.** Info.plist declared the literal
`mwdat-YOUR_META_APP_ID` while the MWDAT dict seventy lines below correctly used
`$(MWDAT_META_APP_ID)`. Underscores are not legal in a URL scheme, which is what the
validator objected to. Confirmed against a real build: MetaAppID resolved to the true
app id while the scheme stayed the placeholder, so this was never about a missing
project.local.yml — the scheme was simply never wired to the setting. If the DAT SDK
uses this scheme for its registration redirect then glasses login has been pointed at a
nonexistent scheme all along, so this is worth more than a validation fix.
Note for CI: this only helps when MWDAT_META_APP_ID actually holds the app id at archive
time. Locally that comes from project.local.yml; Xcode Cloud has no such file, so
project.base.yml's YOUR_META_APP_ID default applies and the scheme stays invalid. Xcode
Cloud needs the app id as an environment variable before a CI archive will validate.
Not addressed here, both out of scope for a source change:
- "Unsupported SDK or Xcode version" — that archive was built with the Xcode 27 beta.
Stable Xcode 26.5 can archive this (it has the iOS 26.5 device SDK); it just cannot
deploy to an iOS 27 handset, which is a separate limitation.
- The seven "Upload Symbols Failed" messages are warnings, not rejections: the vendored
frameworks ship without dSYMs, so crashes inside them will not symbolicate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Verification follow-up: the build finished and the processed (Debug simulator, Still outstanding for a CI archive: Xcode Cloud has no |
|
Correcting the triage in my earlier description (body now updated). I had listed the Xcode-beta message and the URL-scheme message as blockers. Neither is:
The one real blocker is the MediaPipe missing-version-keys rejection, which is a hard ITMS error and new with the Plan CK vendoring. That is fixed and verified. |
Unblocks TestFlight. An upload of 2026.8 surfaced five messages; one is the actual blocker, the rest are long-standing advisories.
The blocker: MediaPipe frameworks have no version keys
Google ships
MediaPipeTasksCommonandMediaPipeTasksVisionwith neitherCFBundleVersionnorCFBundleShortVersionString, andfetch-mediapipe-frameworks.shonly downloaded and moved them — so App Store Connect rejected both bundles ("is invalid. The Info.plist file is missing the required key"). These are hard errors, and new: they arrived with the Plan CK MediaPipe vendoring, so every archive since then would have failed the same way.The script now stamps the pinned version into every slice with
plutil -replace, which adds the key when absent and is therefore idempotent. It also runs on the already-fetched path, so existing checkouts and warm CI caches repair themselves without a 1.2 GB re-download — and sinceci_scripts/ci_post_clone.shcalls the same script, Xcode Cloud is covered.Audited the other five embedded frameworks while here — MWDAT ×3, WebRTC, onnxruntime all carry both keys — so this is the whole of it.
Verified: all four framework slices now carry
1.0.0for both keys; a re-run is a clean no-op and repairs in place without re-downloading.Also: the DAT URL scheme was a hardcoded placeholder
Info.plistdeclared the literalmwdat-YOUR_META_APP_IDwhile theMWDATdict seventy lines below correctly used$(MWDAT_META_APP_ID). Underscores aren't legal in a URL scheme, which is what the validator objected to.This is validation-noise cleanup, not a functional fix. Glasses registration has worked fine for the last month with the placeholder in place, so nothing depends on this scheme today — the SDK uses
MWDAT.MetaAppID, which always resolved correctly. Changing it tomwdat-$(MWDAT_META_APP_ID)simply matches Meta's convention and silences the advisory.Verified: processed
Info.plistresolves tomwdat-688603774243722.Not blockers (no action needed)
Note for CI archives
The scheme fix only takes effect when
MWDAT_META_APP_IDholds the app id at archive time. Locally that comes fromproject.local.yml. Xcode Cloud has no such file, soproject.base.yml'sYOUR_META_APP_IDdefault would apply and the advisory would reappear — cosmetic, given the above, but worth setting as an Xcode Cloud environment variable if you want a clean validation report.Branched off main rather than stacked on #305 so it isn't gated behind that review.
🤖 Generated with Claude Code