SPM for executable binary file. When contain resource like other binary file defined in Package.resource, can't find any resource after swift build

language:

swift version 5.3

Problem:

SPM for executable binary file. When contain resource like other binary file defined in Package.resource, can't find any resource after swift build.

Help

How to solve it?

I'm facing a similar or maybe the same issue.

I have package A with a library which includes some resources (images and a Core Data model). Package B depends on that library and has an executable.

If I run the executable through Xcode things work as expected and the resources from package A can be used. However, if I go through the command line and use swift build and swift run then the resources can't be used (e.g., Bundle.module.image(forResource: named) in the library from package A returns nil). Similarly, if I archive through Xcode and run the resulting executable, the resource bundle is also not usable, though with a different error -- MyLib/resource_bundle_accessor.swift:27: Fatal error: unable to find bundle named MyLib_MyLib.

Any pointers would be highly appreciated!

For the first problem, what kind of resource are we talking about?

For the second problem, you need to make sure to bring along the MyLib_MyLib.bundle with the executable.

I have these resources in my library:

  • .strings files in {lang}.lproj folders
  • PNG and PDF images in an .xcassets catalogue
  • A CoreData model, i.e., a .xcdatamodeld package with .xcdatamodel inside

Should I be able to use these from an executable when using swift build and swift run? (It seems like the bundle is found in that case as I'm not getting the "unable to find bundle" error and instead the look-ups for URLs or images in the bundle just return nil.)

For the case of archiving through Xcode: What do I need to do to "bring along" the bundle with the executable? Is there a setting I need to add to the Package.swift file which defines my executable target (and the dependency on the other package which includes those resources)? FWIW, being able to archive isn't important to me if the swift build would work — I just mentioned that in case it's a hint for some underlying issue.

Many thanks in advance! I'm quite a newbie with command-line work (coming from iOS/macOS apps), so I might be lacking some necessary background knowledge, but I'm excited to extend my skill set and hope to get this working.

  1. Asset catalogues and Core Data models, as well as other Xcode specific resource types are not supported by swift build. IIRC if you are using tools-version 5.5 or later, you'll get a warning for those to make this more obvious.

  2. The bundle is additional content on the filesystem that needs to be present at runtime, so if you e.g. copy the executable somewhere, you will need to copy the resource bundle as well. That's what I meant by saying "bring along".

Got it, thanks. That's very good to know!

The documentation says:

By default, the Swift Package Manager handles common resources types for Apple platforms automatically. For example, you don’t need to declare XIB files, storyboards, Core Data file types, and asset catalogs as resources in your package manifest.

I think that's what tripped me up. I thought that'd also mean that the swift command also handles them. Where would be the appropriate location to document this?

I found a decent workaround for still using CoreData from an executable. Wasn't straightforward, so in case anyone is interested, I wrote up my solution.