Xcode Previews + SwiftPM resources - XCPreviewAgent crashed

Hello all,

There's a really frustrating crash with Xcode Previews because it cannot find the design resources package using the Bundle.module accessor (filed FB9479423). Is there something wrong with the package setup?

I have some Swift packages dependent on another package containing design resources. Xcode Previews do not work because XCPreviewAgent crashes:

CompanyDesign/resource_bundle_accessor.swift:27: Fatal error: unable to find bundle named CompanyDesign_CompanyDesign

Is there some other way packages should be locating their resources, rather than relying on the Bundle.module static property?

Others have been having this issue too. Here's a sample GitHub repo I found.

Our current work around is to build and run a new Xcode app project that includes the package as a dependency, builds the library target and uses the library API in the Simulator (Xcode Previews are a bit hit and miss in this case). But it's a really messy solution requiring us to keep unrelated Xcode projects up to date and working properly.

Any ideas?

Crash log
Process:               XCPreviewAgent [60209]
Path:                  /Users/USER/Library/Developer/Xcode/UserData/Previews/Simulator Devices/4187DDA6-B83B-4A6D-9A63-8BA6E5C73BA2/data/Containers/Bundle/Application/9CE529F9-E954-4303-9BD2-3A04C779C291/XCPreviewAgent.app/XCPreviewAgent
Identifier:            XCPreviewAgent
Version:               13.0 (19073)
Code Type:             X86-64 (Native)
Parent Process:        launchd_sim [59987]
Responsible:           SimulatorTrampoline [59322]
User ID:               501

Date/Time:             2021-08-10 10:39:26.062 +1000
OS Version:            macOS 11.5.1 (20G80)
Report Version:        12
Bridge OS Version:     5.5 (18P4759a)
Anonymous UUID:        EA6339C9-99B4-FD37-88E1-77676FE83B62

Sleep/Wake UUID:       112E14C2-9BD3-4D1C-BD53-8D0843C3E188

Time Awake Since Boot: 130000 seconds
Time Since Wake:       90000 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Illegal instruction: 4
Termination Reason:    Namespace SIGNAL, Code 0x4
Terminating Process:   exc handler [60209]

Application Specific Information:
dyld4 config: DYLD_ROOT_PATH=/Users/kgillard/Downloads/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/kgillard/Library/Developer/Xcode/DerivedData/CompanyPeopleList-euiaatprplkzjxhdopirqrpyuzvg/Build/Intermediates.noindex/Previews/CompanyPeopleList/Products/Debug-iphonesimulator DYLD_INSERT_LIBRARIES=/Users/kgillard/Downloads/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot//System/Library/PrivateFrameworks/XCPreviewKit.framework/XCPreviewKit DYLD_FRAMEWORK_PATH=/Users/kgillard/Library/Developer/Xcode/DerivedData/CompanyPeopleList-euiaatprplkzjxhdopirqrpyuzvg/Build/Intermediates.noindex/Previews/CompanyPeopleList/Products/Debug-iphonesimulator 
CompanyDesign/resource_bundle_accessor.swift:27: Fatal error: unable to find bundle named CompanyDesign_CompanyDesign
 
CoreSimulator 775 - Device: iPhone 12 (4187DDA6-B83B-4A6D-9A63-8BA6E5C73BA2) - Runtime: iOS 15.0 (19A5307d) - DeviceType: iPhone 12

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib            	0x0000000106b482db _assertionFailure(_:_:file:line:flags:) + 427
1   CompanyPeopleList              	0x000000012f673766 closure #1 in variable initialization expression of static NSBundle.module + 2102
2   CompanyPeopleList              	0x000000012f672f19 one-time initialization function for module + 9
3   libdispatch.dylib             	0x000000010bf32c89 _dispatch_client_callout + 8
4   libdispatch.dylib             	0x000000010bf33ed8 _dispatch_once_callout + 20
5   CompanyPeopleList              	0x000000012f673941 NSBundle.module.unsafeMutableAddressor + 49
6   CompanyPeopleList              	0x000000012f6abc2b CompanyImage.safeSwiftUIImage.getter + 955
7   CompanyPeopleList              	0x000000012f6ab6be CompanyImage.swiftUIImage.getter + 142
8   PeopleListView.2.preview-thunk.dylib	0x0000000129529f2d closure #2 in closure #2 in closure #1 in CompanyPeopleListView.__preview__body.getter + 189
9   com.apple.SwiftUI             	0x0000000108760d0e Button.init(action:label:) + 70
10  PeopleListView.2.preview-thunk.dylib	0x0000000129529b9d closure #2 in closure #1 in CompanyPeopleListView.__preview__body.getter + 525
11  PeopleListView.2.preview-thunk.dylib	0x000000012952a8e1 partial apply for closure #2 in closure #1 in CompanyPeopleListView.__preview__body.getter + 17
12  com.apple.SwiftUI             	0x0000000108634c1f HStack.init(alignment:spacing:content:) + 159
13  PeopleListView.2.preview-thunk.dylib	0x0000000129528181 closure #1 in CompanyPeopleListView.__preview__body.getter + 1201
14  PeopleListView.2.preview-thunk.dylib	0x0000000129528631 partial apply for closure #1 in CompanyPeopleListView.__preview__body.getter + 17
15  com.apple.SwiftUI             	0x0000000107f16cfb NavigationView.init(content:) + 48
16  PeopleListView.2.preview-thunk.dylib	0x0000000129527b6e CompanyPeopleListView.__preview__body.getter + 606
17  CompanyPeopleList              	0x000000012f651efe CompanyPeopleListView.body.getter + 142
18  CompanyPeopleList              	0x000000012f654dc1 protocol witness for View.body.getter in conformance CompanyPeopleListView + 17
19  com.apple.SwiftUI             	0x0000000107eda535 partial apply for closure #1 in ViewBodyAccessor.updateBody(of:changed:) + 22
...
...
...```
6 Likes

This is a known issue when using resources of transitive dependencies while previewing a standalone package. Using an app as the preview host as you are doing is the recommended workaround at the moment.

1 Like

Thanks for the reply, in appreciate it because you took the time to confirm I’m on the right track.

Is there anything that can be done about it SwiftPM side that I could contribute towards or do I point people to FB9479423 and endure it in the hope it is fixed one day?

To re-iterate, while I can use Xcode projects, it’s not a great work around because I end up creating lots of unrelated projects that do not keep up with each other (if the APIs in the common package changes, I don’t get compiler errors for unopened projects). I could create less projects but that starts to affect the Xcode Previews ability to respond quickly to source changes.

5 Likes

Yep, I agree that having to create a project is not a good workaround in any way, just wanted to confirm that this is the only way to go right now.

Thanks for offering to contribute, there isn't really anything to be done from the SwiftPM side of things, this all happens inside Xcode. Basically what's happening is that normally resources only get embedded into "top level" targets such as apps, so in theory resources wouldn't work at all for previews of standalone packages. We implemented a minimal solution to support resources in the package you are actively previewing and what's missing is tackling this for transitive dependencies as well.

2 Likes

I’ve had some luck with this workaround.

That seems to fix the issue as long as the file you are previewing is directly included as a dependency in the app target. If it’s not, you need to set your active scheme to the scheme that owns that file. It’s a lot better than having to add additional app targets though!

2 Likes

Thanks for sharing this! My team is trying this to mitigate Xcode project explosion until the Xcode build system can deal with all resources of the dependency graph.

I have the same problem while developing a multi-module iOS app. The question I have is if multiple module create their own Bundle extension with the same variable how Swift resolves the ambiguity? In Objective-C there is no guaranty if two modules add the same method/var in a type using a category which will be called, in Swift is there anywhere documented how this is handled?

Hi, is there any hope on this one?

1 Like

This workaround worked for me:

Really looking forward to a solution on this, since modularisation is becoming more common every day.

5 Likes

Using the SPM Plugin mechanism I've implemented this workaround by automatically generating the Bundle extension (called Bundle.current) during the prebuild phase.
It does work quite well for our project with multiple modules providing resources that are shared across targets .
An example implementation can be found here GitHub - ctreffs/swiftui-previews-module-resources-fix: Swiftui Xcode previews module resources fix

Would appreciate some feedback from the community before converting this into a standalone plugin package.

Hope this helps some of you with this problem :slightly_smiling_face:

1 Like

Thanks @ctreffs for the plugin,

Do you think you can propose a PR to GitHub - apple/swift-package-manager: The Package Manager for the Swift Programming Language if the new Xcode does not fix this ?

Thanks,

I could do that, but as @NeoNacho already stated that is not a SPM thing to fix at least as far as I understand this. Opening a PR to SPM for this would leak Xcode specific implementation details to SPM which is not intended.

2 Likes

It looks like Xcode 16 has broken this again?

When running previews the bundle found is pointing at an XCPreviewAgent.app and it isn't possible to get to the bundle path from there.

I've tried using @ctreffs package. And wrote it myself too/ But I just can't get previews to work when showing assets from a different module.

:frowning:

@Fogmeister We fixed a bug that could cause this symptom in Xcode 16.2 beta 1 (if it's previewing an iOS app in the simulator) / macOS 15.2 beta 1 (if it's previewing a macOS app) / iOS 18.2 beta 1 (if using an on-device preview for iOS). If you're able to try the beta and still see the issue, please file a feedback with Apple so we can look into it further.

1 Like

Oh! Interesting! Thank you!

Does that mean that in Xcode 16.2b1 we won't need this BundleFinder fix at all?

Or will we still need the BundleFinder but the previews will still work?

Thanks very much!

Going to give it a try in the morning!

I'm not aware of any changes to embedding of package resources, so I would assume you would still need this workaround if you needed it before (maybe worth double checking though!). I was only commenting on a regression in Xcode 16 where it was finding the main app instead of the correct bundle path.

1 Like

I have two packages. One for a feature, another containing design resources (icons, illustrations, colours etc). The feature package is dependent on the design package and the feature implementation accesses resources provided by the design package. Using Xcode 16.2 beta 1, I was able to remove the BundleFinder type and associated code in the design package and preview the feature package with Xcode Previews without crashes. To rule out false positives, I reset the package cache, cleared the build folder and re-opened Xcode.

This is very positive news and I hope you have similar findings!

1 Like

OK, confirmed.

I've installed Xcode 16.2b1 and it fixes the Previews. The Previews even work when I remove the BundleFinder fix mentioned in this thread.

However, the BundleFinder fix is still required for tests that execute code that accesses assets. (i.e. snapshot tests in other frameworks).

Thanks for the help :slight_smile:

Looking forward to the day that Apple finishes the work they started on Xcode generated asset symbols and allows us to make them public. :sweat_smile:

3 Likes

On a semi related note, could you ping whoever it is that controls the Xcode release notes to get them updated with notes for fixes like this? Right now 16.2b1 shows nothing.

3 Likes

Wow, I had an epic battle with packages to fix it in 16.0 (and I won), but my colleagues just figured out this thread and confirm that it works with 16.2beta without any changes. About four days of developer productivity down the drain.

What happened:

  • Local packages set-up
  • We are re-using SharedModel and SharedUI across all packages
  • One of these packages is called Identity and takes care of all things related to sessions and identity
  • We created a new module for the home screen, that imported SharedUI
  • We were adding a profile related screen there, that needed Identity to get the current profile
  • As soon as we added Identity (for it's logical / data side), previews stopped working with bundle errors

I tried the following:

  • Created a new package for the profile screen
  • Suspected a UI-in-UI issue, or an issue where SharedUI was imported from two sides and it got confused. Split up Identity in IdentityDefinitions (only logic + data + SharedModel) and IdentityUI (only UI + IdentityDefitions) -- this didn't work
  • Then I started suspecting that we might have an issue in SharedModel. It had some third party libraries for legacy reasons. Butchered out the third party libraries -- stuff started working

It turned out that in this particular sequence of attempts to fix it the last step of removing an HTML conversion related library fixed the issue.

So a certain combination of them fixed the issue. Just getting rid of the third party library for HTML without any of the other changes still had the issue under 16.0

Xcode 16.2 beta did not need any of these changes.