Skip to content

Settle iOS read and write semantics - #27

Merged
friederbluemle merged 2 commits into
fbluemle:masterfrom
friederbluemle:ios-read-semantics
Sep 4, 2026
Merged

friederbluemle merged 2 commits into
fbluemle:masterfrom
friederbluemle:ios-read-semantics

Conversation

@friederbluemle

Copy link
Copy Markdown
Contributor

The iOS reads were inconsistent with each other and with the writes. getIOSAppId resolves the application target's build configuration, but getIOSVersions took the first MARKETING_VERSION / CURRENT_PROJECT_VERSION in the file. Xcode sorts XCBuildConfiguration objects by id, so "first" is arbitrary: in the stock React Native template the test target's configurations sort before the app's, and --print-env ios combined the app id of one configuration with the versions of another target. Meanwhile the write side replaced every occurrence without saying so, and silently did nothing when there were none.

Settled semantics, one commit each:

  • Reads: the application target's configuration, for all values. MARKETING_VERSION, CURRENT_PROJECT_VERSION and PRODUCT_BUNDLE_IDENTIFIER all come from the application target's build configuration named by --configuration (default Release), which now applies to every --print* flag for ios rather than only the app-id ones. A setting missing from the target's configuration falls back to the project-level configuration of the same name, as Xcode resolves it, so projects that keep versions at the project level keep working. A value that is a build setting variable is rejected for versions too, not only for the app id. xcconfig files are still not read.
  • Writes: every target, never a no-op. Syncing still replaces every MARKETING_VERSION and CURRENT_PROJECT_VERSION in the file; that is intentional and now documented, since Xcode requires extensions to carry the same version as their containing app. A project.pbxproj without those settings, or a build.gradle without versionName / versionCode, was reported as synced although nothing was written; both updaters now fail with the same "No X found" error the readers use.

The test fixture emits a PBXProject object with its own configuration list (matching Xcode's layout) so the fallback path is covered, and build configurations can omit version settings to test the failure cases.

One limitation stays: a project with several application targets can no longer read iOS versions, because there is no way to say which target. --print-app-id already had that restriction. A --target option would lift it if the need comes up.

Reading versions from a different target than before is a behavior change, so this should go out as a minor release.

getIOSVersions returned the first MARKETING_VERSION and
CURRENT_PROJECT_VERSION in project.pbxproj, while getIOSAppId already
resolved the application target's build configuration. Xcode sorts
XCBuildConfiguration objects by id, so "first" was arbitrary: in the
stock React Native template the test target's configurations come
before the app's, and --print-env ios combined the app id of one
configuration with the versions of another target.

All three iOS values now come from the application target's
configuration named by --configuration, which applies to every --print*
flag for ios instead of only the ones involving the app id. A setting
missing from the target's configuration falls back to the project-level
configuration of the same name, as Xcode does, so projects that keep
their versions at the project level keep working. The test fixture
gained a PBXProject object with its own configuration list to cover
that path.
A build.gradle without versionName / versionCode or a project.pbxproj
without MARKETING_VERSION / CURRENT_PROJECT_VERSION (for example an
older project that keeps literal values in Info.plist) was reported as
synced although nothing was written. Both updaters now throw the same
"No X found" error as the readers, so the sync fails instead of
pretending. The README also states why iOS writes touch every target:
Xcode requires extensions to carry the same version as their app.
@friederbluemle
friederbluemle merged commit 9ac3b0d into fbluemle:master Sep 4, 2026
3 checks passed
@friederbluemle
friederbluemle deleted the ios-read-semantics branch September 4, 2026 07:06
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🎉 Released in v0.7.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant