Bundle for static library resources? (iOS)

Xcode 9 introduced support for compiling frameworks containing Swift as static libraries. Prior to converting my dynamic frameworks, resources from "Copy Bundle Resources" build phase could be found by looking for the filename in Bundle(for: MyClass.self). After converting to a static library, the file can no longer be found in that bundle. Nor can it be found in the main bundle. Where do these files end up? They are still listed in "Copy Bundle Resources", everything compiles fine, and I see the files in the resulting build folder.

Replies

>> Xcode 9 introduced support for compiling frameworks containing Swift as static libraries.


That's not really what it said (https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html):


"Xcode supports static library targets which contain Swift code"


In other words, you can build static libraries from Swift source. However, static libraries are still just compilations of object files (multiple .o files in one .a file). Their identity disappears when they're linked into an executable target (app binary or dynamic library), and they bring no resources other than code and constant data.


It may be slightly more complicated than this (the library might be built with an associated folder of relevant header files, and perhaps resource files, too), but those additional files don't really have an special status AFAIK. (I haven't bothered to understand the structure in detail, because static libraries are generally more trouble than they're worth in Xcode. Certainly, because of the non-stable Swift ABI, you can't usefully distribute Swift-sourced static libraries.)

Were you ever able to figure this out? I'm running into the same issue. Thanks!

Were you ever able to figure this out? I'm running into the same issue.

Figure what out, exactly? QuinceyMorris clearly explained the fundamental misconception that was confusing tspike2. Beyond that, it’s a tradeoff between the benefits of a static library (notably, faster launch times) and the benefits of a framework (including easier resource management).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I think the question @Craig_MSI asked was "How to access the resources (for example, Localizable.strings), in the static library/framework?".
I have the same question for accessing the Localizable.strings in a static framework from the bundle path, please kindly answer us in this thread.

How to access the resources (for example,

Localizable.strings
), in the static library/framework?

Again, this question makes no sense because:

  • There’s no such thing as a “static framework”. Frameworks, by definition, are dynamic.

  • A static library doesn’t have its own bundle structure and, as such, can’t carry resources.

There is, however, some good news on this front. Starting with Swift 5.3 it should be possible to use resources in a Swift package. See SE-0271 Package Manager Resources and SE-0278 Package Manager Localized Resources for the details.

AFAIK there’s no concrete release date announced for Swift 5.3. See Swift 5.3 Release Process for the announced plan.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Did you ever find a workable solution for this problem? I'm in a situation where I have a custom framework that has a static library as a dependency. At launch I was seeing a huge list of warnings about "Class <...> is implemented in both...", apparently indicating that both the app and the framework were including the dependency (despite the fact that the app doesn't import that dependency anywhere...). The static library (AudioKit) is being included in my custom framework using Cocoapods.

To get around the warnings I tried switching my mach-O target from "Dynamic Library" to "Static Library", based on a note I read somewhere about not adding static libraries as dependencies in dynamic frameworks. Sure enough, this removes the warnings, but then it fails when trying to load resources from inside the framework's bundle using "Bundle(for: <myFrameworkClass>.self)", as you've indicated in your question. (Note that I responded to the warnings not simply because they looked serious(!) but rather because my framework wasn't working properly.)

The answers here, unfortunately, are non-answers... While I understand what they're trying to say, there's clearly some broad misunderstanding going on far beyond this thread, as the framework I'm using, AudioKit, is referred to as "static" in many places online—including AudioKit's home page. Also, when I compile my custom framework with "Static Library" indicated, I very definitely get a bundle in the product package, complete with all the resource files I'm trying to access at launch (i.e., the ones that aren't found because the bundle path is now the app's, not the framework's). Clearly this is super frustrating. The only thing I can think of doing now is grabbing the main bundle's path, and appending the path to my framework. Feels hackish, but I feel like I'm painted into a corner here, so really not sure what else to do...


Just as an update, I tried both hacking in the path to the framework resources (mentioned above), and using a resource bundle; in both cases I got a permission error at runtime...

@jbmaxwell Were you able to solve the issue ?