Skip to content

Commit 9fe5eb6

Browse files
shai-almogclaude
andauthored
iOS: honor ios.teamId in locally-generated Xcode projects (#4941) (#4945)
The build hint was wired only into the cloud builder's provisioning-profile plist, so locally generated projects always opened with Team: None. Inject DEVELOPMENT_TEAM into the project-level Debug/Release XCBuildConfiguration blocks, resolving ios.debug.teamId / ios.release.teamId with fallback to ios.teamId — matching the cloud builder's precedence. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7bb87a9 commit 9fe5eb6

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/IPhoneBuilder.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import java.util.*;
4242
import java.util.logging.Level;
4343
import java.util.logging.Logger;
44+
import java.util.regex.Matcher;
45+
import java.util.regex.Pattern;
4446

4547
/**
4648
*
@@ -2281,6 +2283,11 @@ public void usesClassMethod(String cls, String method) {
22812283

22822284
addLocalizedIconsBuildSetting(pbxprojFile);
22832285

2286+
String teamId = request.getArg("ios.teamId", "");
2287+
injectDevelopmentTeam(pbxprojFile,
2288+
request.getArg("ios.debug.teamId", teamId),
2289+
request.getArg("ios.release.teamId", teamId));
2290+
22842291
} catch (Exception ex) {
22852292
throw new BuildException("Failed to inject into plist");
22862293
}
@@ -3486,6 +3493,66 @@ private void writeAlternateAppIconContentsJson(File contentsJson,
34863493
}
34873494
}
34883495

3496+
// Apple Team IDs are 10-character alphanumeric strings (e.g. "2K4UGY23XQ").
3497+
// Anything outside that range is rejected to avoid corrupting the pbxproj.
3498+
private static final Pattern TEAM_ID_PATTERN = Pattern.compile("[A-Za-z0-9]+");
3499+
3500+
private void injectDevelopmentTeam(File pbx, String debugTeam, String releaseTeam) throws IOException {
3501+
debugTeam = sanitizeTeamId(debugTeam, "ios.debug.teamId");
3502+
releaseTeam = sanitizeTeamId(releaseTeam, "ios.release.teamId");
3503+
if (debugTeam.isEmpty() && releaseTeam.isEmpty()) {
3504+
return;
3505+
}
3506+
String contents = readFileToString(pbx);
3507+
// Anchor on each XCBuildConfiguration's "buildSettings { ... }; name = Debug|Release;"
3508+
// boundary so we can route the right value per configuration when ios.debug.teamId
3509+
// and ios.release.teamId differ. DEVELOPMENT_TEAM is injected at the project level
3510+
// (the configurations that declare SDKROOT) so it inherits to every target.
3511+
Pattern blockPattern = Pattern.compile(
3512+
"buildSettings = \\{.*?\\};\\s*name = (Debug|Release);",
3513+
Pattern.DOTALL);
3514+
Matcher m = blockPattern.matcher(contents);
3515+
StringBuffer out = new StringBuffer();
3516+
boolean modified = false;
3517+
while (m.find()) {
3518+
String block = m.group(0);
3519+
String configName = m.group(1);
3520+
String team = "Debug".equals(configName) ? debugTeam : releaseTeam;
3521+
if (team.isEmpty()
3522+
|| block.contains("DEVELOPMENT_TEAM")
3523+
|| !block.contains("SDKROOT = iphoneos;")) {
3524+
m.appendReplacement(out, Matcher.quoteReplacement(block));
3525+
continue;
3526+
}
3527+
String injected = block.replace(
3528+
"SDKROOT = iphoneos;",
3529+
"SDKROOT = iphoneos;\n\t\t\t\tDEVELOPMENT_TEAM = " + team + ";");
3530+
m.appendReplacement(out, Matcher.quoteReplacement(injected));
3531+
modified = true;
3532+
}
3533+
m.appendTail(out);
3534+
if (modified) {
3535+
try (Writer w = new OutputStreamWriter(Files.newOutputStream(pbx.toPath()), StandardCharsets.UTF_8)) {
3536+
w.write(out.toString());
3537+
}
3538+
}
3539+
}
3540+
3541+
private String sanitizeTeamId(String raw, String hint) {
3542+
if (raw == null) {
3543+
return "";
3544+
}
3545+
String trimmed = raw.trim();
3546+
if (trimmed.isEmpty()) {
3547+
return "";
3548+
}
3549+
if (!TEAM_ID_PATTERN.matcher(trimmed).matches()) {
3550+
log("Ignoring " + hint + "='" + raw + "': expected an alphanumeric Apple Team ID");
3551+
return "";
3552+
}
3553+
return trimmed;
3554+
}
3555+
34893556
private void addLocalizedIconsBuildSetting(File pbx) throws IOException {
34903557
if (localizedIcons.isEmpty()) {
34913558
return;

0 commit comments

Comments
 (0)