Skip to content

Nested SystemCapabilities target attribute is serialized as a quoted Swift dictionary #1637

Description

@gigq

XcodeGen version

Burned first recorded this output on 2026-07-14, when 2.45.4 was the current release. The 2.46.0 source still passes nested target attributes through ProjectAttribute(any:); I am adding exact version output to the downstream CI reproduction and will comment with that result.

Minimal project spec

name: CapabilityRepro
targets:
  CapabilityRepro:
    type: application
    platform: iOS
    attributes:
      SystemCapabilities:
        com.apple.HealthKit:
          enabled: 1

Actual generated project.pbxproj

SystemCapabilities = "[\"com.apple.HealthKit\": [\"enabled\": 1]]";

The nested dictionary is emitted as a quoted Swift dictionary description. Xcode expects SystemCapabilities to be a PBX dictionary, so a downstream post-generation hook currently has to replace it.

Expected output

SystemCapabilities = {
    com.apple.HealthKit = {
        enabled = 1;
    };
};

Downstream context

The tracked workaround is in codesmithing-dev/Burned#67. It validates the exact malformed shape before rewriting it and will deliberately fail once XcodeGen emits the native PBX dictionary so the hook can be retired.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions