feat: add traits to XCRemoteSwiftPackageReference and XCLocalSwiftPackageReference#1114
Merged
Merged
Conversation
chigichan24
commented
Apr 19, 2026
pepicrft
approved these changes
Jul 13, 2026
pepicrft
left a comment
Contributor
There was a problem hiding this comment.
Validated against current main. The implementation preserves absent, empty, and populated package trait selections, includes traits in equality, and keeps project read and write operations stable. The full test suite and repository lint command pass.
pepicrft
approved these changes
Jul 13, 2026
pepicrft
left a comment
Contributor
There was a problem hiding this comment.
Revalidated at the current head. The package traits model and project read and write coverage are sound. The availability fallback preserves iOS 12 build compatibility while retaining the optimized path on newer systems. All repository workflows pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
This pull request adds optional
traits: [String]?support to bothXCRemoteSwiftPackageReferenceandXCLocalSwiftPackageReference.XcodeProj now:
Why
Xcode 26.4 writes Swift Package Manager package traits on package-reference objects:
Without model support, reading and writing one of these projects silently removes the trait selection. Xcode then falls back to the package defaults the next time the project opens.
The branch also needed to remain buildable for the package's existing iOS 12 deployment target after being updated to current
main.Root cause
The package-reference models did not decode, store, serialize, or compare the
traitsfield introduced by Xcode.While adding equality coverage, the implementation also exposed an older generated-equality gap for
XCLocalSwiftPackageReference. Its relative path was not part of equality, so local references with different paths could compare as equal.Separately, current
mainuses a string initializer introduced in iOS 14 from code compiled for iOS 12. This only surfaced after the pull request workflows moved to the latest Xcode runner.Approach
Traits use
[String]?to preserve the project file exactly:nilmeans no explicit selection, so package defaults apply.[]means default traits are explicitly disabled.An array is used instead of a set because Xcode project arrays preserve source-file order.
The selection remains on the local or remote package reference. Product dependency objects are unchanged because Xcode does not write traits there.
A dedicated fixture covers a populated local selection and an explicitly empty remote selection. The integration test verifies that reading and writing the fixture produces no diff.
String escaping keeps the direct-storage implementation where that initializer is available. Older supported systems use the same escaping routine through a byte buffer.
Impact
Projects using package traits can now be safely read, modified, and written with XcodeProj without losing their trait configuration. Existing callers remain source compatible because the new initializer arguments default to
nil.The package also continues to compile for its existing iOS 12 deployment target.
Validation
mise run lintmise run test: 381 XCTest tests and 6 Swift Testing tests passed.xcodebuild build -scheme XcodeProj -destination 'generic/platform=iOS Simulator'xcodebuild test -scheme XcodeProjon an iPhone 17 Pro simulator running iOS 26.5: 323 XCTest tests and 6 Swift Testing tests passed, with 5 expected skips.