Hive
ObjC dynamic framework SPM dependencies missing Tuist-derived bundle accessor files since 4.146.0
GitHub issue · Open
What happened?
After upgrading from Tuist 4.145.0 to 4.146.0, ObjC SPM dependencies configured as dynamic frameworks (.framework) fail to compile because the tuist-derived bundle accessor files (TuistBundle+<Target>.h and TuistBundle+<Target>.m) are not wired into the generated Xcode project:
- The
.hfile is not set inGCC_PREFIX_HEADER - The
.mfile is not added to the compile sources build phase - The
tuist-derivedfolder does not appear in the Xcode project navigator
The files are generated on disk but simply not referenced by the project.
This was introduced by PR #9446 (revert static framework resource embedding). The condition in ResourcesProjectMapper.mapTarget changed:
// Before (4.145.0):
let shouldGenerateResourceBundle = !supportsResources && target.product != .staticFramework
// After (4.146.0):
if !target.supportsResources || target.product == .staticFramework {
For dynamic frameworks, supportsResources is true and product != .staticFramework, so false || false evaluates to false — the entire resource mapping block is skipped, including the logic that wires synthesized TuistBundle+ files into the Xcode project.
How do we reproduce it?
- Add an ObjC SPM dependency that has resources (e.g., AffirmSDK)
- Configure it as a dynamic framework in
Package.swift:
let packageSettings = PackageSettings(
productTypes: [
"AffirmSDK": .framework,
]
)
- Run
tuist generate - Build — compilation fails with
Use of undeclared identifier 'SWIFTPM_MODULE_BUNDLE'
Error log
/path/to/Tuist/.build/checkouts/affirm-merchant-sdk-ios/SPM/AffirmUtils.m:62:12
Use of undeclared identifier 'SWIFTPM_MODULE_BUNDLE'
macOS version
26.3
Tuist version
4.146.0 (first regression version after 4.145.0)
Xcode version
26.3
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
Hi @Fab1n! I’m Dosu and I’m helping the tuist team.
Your analysis looks correct. The condition in ResourcesProjectMapper.swift that gates TuistBundle+ file generation:
if !target.supportsResources || target.product == .staticFramework {
…causes dynamic frameworks (where supportsResources=true and product != .staticFramework) to skip the entire block, including the ObjC bundle accessor generation logic that wires TuistBundle+<Target>.h/.m files into the project.
This appears to be an unintended regression from PR #9446, which reverted static framework resource embedding to fix App Store rejections. The logic change inadvertently created a gap where ObjC dynamic framework SPM dependencies with resources no longer get their bundle accessor files wired.
For debugging this further, you might want to install Tuist’s debug-generated-project skill following the steps in tuist/agent-skills and use a coding agent to trace through the exact code paths.
If you can provide a minimal reproducible project, that would help the maintainers confirm and fix this regression.
To reply, just mention @dosu.
Docs are dead. Just use Dosu.