inExternalTesting property
Whether external testers can install this build now, or null when that cannot be said.
Nullable rather than false-by-default, and the choice is the one
usable argues in the other direction. That flag gates an action —
releasing a build whose state is not understood — so failing closed to
false is a refusal and is safe. This one gates a report: false
here is the claim external testers do not have this build, and making
an unread relationship or an unnamed state say it out loud is the defect
this field was added to fix rather than a safe default. Null says the
question was not answered, which is what a consumer should show.
False for an expired build whatever else is true of it. TestFlight
withdraws a build after ninety days, so a build that cleared review and
is attached to an external group is still one nobody can install — and
this answered true for exactly that combination until review caught it.
The false is a refusal like usable's rather than a claim, and it is
the one reading here that does not need betaGroups to have been read.
Two facts and not one, once it is not expired: true when the build has cleared beta review — ExternalBuildState.betaApproved, ExternalBuildState.readyForBetaTesting or ExternalBuildState.inBetaTesting — and betaGroups holds at least one group whose kind is BetaGroupKindEntry.external. Apple's verdict is not delivery, and an attachment made while review is still pending is not delivery either, so neither half answers on its own.
Reading the state alone was this field's first shape, and it was a
constant false against a real account: over 51 iOS builds measured
2026-09-14, Apple's terminal external state after review is
BETA_APPROVED and IN_BETA_TESTING did not occur once, so fourteen
builds external testers demonstrably had reported that they did not.
Null when this listing was answered short and the missing part could
have changed the answer — see unresolvedBetaGroups and
unresolvedBuildBetaDetail, which say which of the two inputs went
missing and are 0 and false on a complete read.
The qualifier is load-bearing and this said null when answered short
without it, which is wrong in the one case a reader would hit first: a
build with a resolved external group and a shortfall beside it answers
true, because the groups that did not arrive could only have added
attachments. A shortfall makes an empty external list uninformative,
not a non-empty one.
Implementation
final bool? inExternalTesting;