Fix asset color resolution for Xcode-built preview targets (#151)#152
Merged
Fix asset color resolution for Xcode-built preview targets (#151)#152
Conversation
`Generated*Symbols.swift` (asset/string/plist symbols emitted by Xcode) contain a `Bundle(for: ResourceBundleClass.self)` lookup that resolves to whichever binary defines `ResourceBundleClass`. When PreviewsMCP recompiled these files into the Tier 2 bridge dylib, that binary became the bridge dylib itself — which has no `Assets.car` — so `Color(.brandPrimary)` and similar lookups silently returned nothing, leaving views (e.g. ToDoView's TabView page bodies) blank under .xcodeproj/.xcworkspace. XcodeBuildSystem now writes a transformed copy of each `Generated*Symbols.swift` to `<DERIVED_FILE_DIR>/PreviewsMCPRewrites/`, replacing the resource-bundle preamble with `Bundle(path: "<CODESIGNING_FOLDER_PATH>") ?? Bundle.main`. SPM and Bazel paths are untouched. Also adds `Log.info` lines in `Compiler.compileCombined` and `BuildHelpers.detectAndBuild` (the build-system / extraFlags surface was silent in serve.log, which made the original diagnosis painful), and documents Xcode and Bazel artifact layouts uniformly with the existing SPM section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the BUILT_PRODUCTS_DIR/WRAPPER_NAME fallback; CODESIGNING_FOLDER_PATH is the load-bearing input and the fallback could resolve to a non-existent path, silently re-introducing the bug it was meant to prevent. - Add fileExists guard with a warning log when CODESIGNING_FOLDER_PATH doesn't point at a real wrapper on disk; fall back to the original sources rather than producing a Bundle(path:) that returns nil. - Extract the rewrite loop into `applyResourceBundleRewrites(sources:settings:)` so it's directly testable without spinning up xcodebuild. - Add three integration tests covering: happy-path fan-out across multiple Generated*Symbols.swift files, missing CODESIGNING_FOLDER_PATH, and CODESIGNING_FOLDER_PATH pointing at a non-existent path. - Fixes the swift-format strict lint error at line 140. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 7 new tests in 1d4f43a pushed BuildSystemTests' struct body to 1025 lines, just past SwiftLint's 1000-line type_body_length cap. Move them verbatim into ResourceBundleRewriteTests to keep both suites under the cap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Color(.brandPrimary)(and anyColorResource/ImageResource) silently resolving to no color when the bridge dylib is built against an Xcode framework target. ToDoView's TabView page bodies appeared blank becauseSummaryCard.background(color.gradient)painted nothing.Generated*Symbols.swiftfiles useBundle(for: ResourceBundleClass.self)to find the resource bundle. When recompiled into the bridge dylib,ResourceBundleClasslives in the dylib (noAssets.car), so asset lookups silently return nothing. SPM and Bazel weren't affected because their examples used system colors only — not because their build paths are immune.XcodeBuildSystemnow rewrites anyGenerated*Symbols.swiftsource on the way into Tier 2, replacing the broken preamble withBundle(path: "<CODESIGNING_FOLDER_PATH>") ?? Bundle.mainand writing the transformed copy to<DERIVED_FILE_DIR>/PreviewsMCPRewrites/.Log.infoinCompiler.compileCombined(extraFlags) andBuildHelpers.detectAndBuild(selected build system) — both were silent inserve.logand made the diagnosis painful.docs/build-system-integration.md.Test plan
swift test --filter BuildSystem— 68/68 passing, including 4 newrewriteResourceBundletests covering the happy path, two negative cases, and path-escape edge cases.examples/xcodeproj/Sources/ToDo/ToDoView.swiftrenders the Progress card (blue gradient + "1/8" + "7 remaining" + page dots) correctly.examples/xcworkspace/Sources/ToDo/ToDoView.swiftrenders correctly.examples/xcodeproj/Sources/ToDo/ToDoView.swiftrenders correctly (no longer dim/translucent)..bluecontrol vs.Color.brandPrimary): brandPrimary now paints; before the fix it rendered as no-color.nmconfirmedResourceBundleClasslives in the Xcode bridge dylib but not in SPM's, matching the proposed mechanism.🤖 Generated with Claude Code