Using dynamic framework which is linked with static framework

Trying to prepare a single dynamic framework to my customer. My framework (A.framework) uses third-party recognition static framework (B.framework). I can't provide separate A and B frameworks to the customer. Ideally B.framework should be built and included into my A.framework's binary, so the customer's app will only embed A.framework without any additional actions to link with that third-party app.

What I did:

  1. Added B.framework to the project.
  2. Added B.framework to "Linked Frameworks and Libraries" in the corresponding target.
  3. Built A.framework.
  4. Created a demo application and included A.framework to the project.
  5. Added A.framework to "Embedded Binaries".
  6. Demo app's build fails with message "Missing required module 'B'" (despite the fact that it is used in A.framework only).

Note:

  • I neither created any modulemap files for B.framework, nor additional run scripts
  • Making A.framework static is not acceptable because it includes some resources (storyboards, icons and some other files)
  • Tried to make un-recommended "umbrella" framework but got stuck on loading B.framework's bundle in demo app
  • Tried to make fake "umbrella" framework by simply copying B.framework inside A.framework, but got 2 problems - huge size of A.framework and Mach-O error while exporting the demo application (because of Mach-O difference between dynamic A and static B frameworks)
  • All the projects have disabled bitcode


UPD 1: This is not about umbrella framework because the proper umbrella framework implementation requires to load sub-framework from bundle which is not good. The fake framework implementation (sub-framework simply copied to umbrella) won't work for release because of different Mach-O values - dynamic and static. Plus fake umbrella framework has a huge size because sub-framework is being fully copied inside umbrella.

UPD 2: Created a small test project: StaticFrameworkTest which has 3 sub-projects:

  1. Demo-application with dynamic framework dependency (framework A) and shouldn't know anything about framework B
  2. Dynamic framework with static framework dependency (framework B) which ideally should be included in A framework's binary.
  3. Static framework B

UPD 3: After comprehensive search of a solution found similar thread here: https://forums.developer.apple.com/thread/86056. Similar to my case, @akhilcb faced an issue when he could build the project on my machine, but not on another (got "Missing required module Static Framework" error). Cleaning "Derived Data"doesn't help.


Any ideas would be highly appreciated!

Accepted Reply

Finally, the issue is resolved. I had to build static framework that contains other dependent frameworks, link this static framework with the application (not embed) and specify "Framework Search Paths" to the inner frameworks.

Add a Comment

Replies

There really is no such thing as a "static framework". Putting a dynamic framework wrapper around a static library (which seems to be what you've done) might work in some situations, but AFAIK it's not supported by Xcode.


If B is actually written in Objective-C, you can pull out the static library and the header file(s) and use those directly in your A framework. (The point is not to import the B module file.)


If B is actually written in Swift, I doubt there's a solution without some kind of manual edit to A's module file. In this case, you might try asking over on forums.swift.org to see if there's anything you can do about it.

QuinceyMorris, thank you for your reply!

Yes, seems like framework B is actually Objective C static library wrapped in framework.



Could you please guide me or provide a link to detailed information how to import static library properly inside my Swift framework? I'm still getting "Missing required module 'B'". I did the following:

  1. Unwrapped framework B, changed binary name from B to B.a
  2. Added all the headers of framework B and the library file B.a to my framework
  3. Setup Import Paths and Library Search Paths
  4. Added module.modulemap file:
module B [system] {
    header "include/B.h"
    export *
}



Then built my framework successfully and included into Swift demo application to Embedded Binaries.

Everything works on my machine, but if I try to build the demo application (which contains my framework), I'm getting "Missing required module 'B'".

Looks like I need to expose something from library B, but not sure.


I was following these manuals:

This is outside my expertise, but my guess is that your module map file implies that module B is public, which means module A carries a reference to it into the main app, and at that point the B symbol can't be resolved.


I would suggest you take this over to forums.swift.org, and see if one of the experts can advise you on how to put this together.

Asked. Thank you for your help!

Finally, the issue is resolved. I had to build static framework that contains other dependent frameworks, link this static framework with the application (not embed) and specify "Framework Search Paths" to the inner frameworks.

Add a Comment

i did not get your solution can you please elaborate it. thanks

Could you please elaborate the solution, I am also having exactly same situation.

Appreciate your help!

Here is a bit of extra info that may be useful: https://github.com/Carthage/Carthage/issues/2618#issuecomment-672074666