7

As i understand the big change from ios dynamic framework and static is that static is linked statically to the code at link time (prior to launch) and dynamic is linked at launch/runtime

Now i have a test project:

My project have a dynamic framework linked to it - A.framework.

import A.framework

A.framework have a framework embedded inside of it - B.framework

In my main project i want to use classes from B.framework

Now i see that with a simple import statement in the main project:

import B.framework

It actually work and i can use code from inside of the B.framework which is embedded in linked A.framework

How can it be? is it something that is safe and reliable to use? How does the main project recognize the B.framework?

What about cases where the main project directly link the B.framework to the project? in this case i see many "duplicate symbol errors" at link time

Most importantly how can i build A.framework while not embedding B.framework inside of it, while off course using its classes and functions

Any clarifications will help :)

Michael A
  • 5,770
  • 16
  • 75
  • 127

1 Answers1

7

As you note, linking B.framework would lead to duplicate symbols. This is why A.framework should not embed B.framework. You must never embed a framework in another framework if there is any chance that the consuming application will care about the embedded framework (in practice, this means you really should just never do it).

A.framework was incorrectly packaged. If you packaged it, you should remove the embedded framework and link everything at the application layer. If someone else packaged it, you should open an issue with them to correct this error. This issue is not new to dynamic frameworks. It was equally a problem with static frameworks. The only appropriate time to link dependencies is at the application layer.

(There is an exception if you control the entire ecosystem (e.g. Apple). Then things like umbrella frameworks are acceptable. But you're not Apple.)

EDIT: It is ok to link, but not embed, a shared framework into another shared framework. The key is that the only copy of the shared framework needs to come from the top-level application. Since that final link step will happen at load, then you won't have duplicate symbols because there is only one copy of the shared framework. Just don't embed the sub-framework into yours.

For example:

  • Create project with framework target
  • Drag in GMA.framework to framework target (this will cause it to link but not embed)
  • Create App target
  • Have app link both GMA.framework and your test framework. This will work fine without collisions because there is only one GMA.framework, and it's only embedded in the app.
Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • But what if i have to use code from B.framework inside my A.framework? If i dont link B.framework to A.framework i cant use its functionality which in this case i can't implement my self since it is a third party framework – Michael A Jan 04 '16 at 07:54
  • 1
    You just need to *import* B into A. You don't have to *link* B into A. As long as the final app links both B and A, then it will all work. That's what linkers are for. A framework doesn't have to be able to resolve all its symbols as long as it can resolve them by the time the app runs. – Rob Napier Jan 04 '16 at 14:10
  • The problem is that if dont link the B to A the framework project dont build and get errors of symbols undefined as i explain in that question: http://stackoverflow.com/questions/34609229/undefined-symbols-issue-with-googlemobileads – Michael A Jan 05 '16 at 12:22
  • Are you linking GMA into your final application? You mean the framework itself doesn't build without linking GMA? I can't reproduce that problem. In my test, I create a new framework project, drop another framework project into it. Make the second framework a dependency of the first, "import B" into A and then create a "B" object in A. It builds fine. But any final application that links B needs to also link A. – Rob Napier Jan 05 '16 at 14:01
  • I mean the framework itself don't build giving me undefined symbols. What do you mean "make the second framework a dependency of the first" ? how do you do it technically without linking it? Will really appreciate your help our guys here are stuck on that issue for a very long time – Michael A Jan 05 '16 at 14:59
  • Build Phases>Target Dependencies. Add the second project's target. – Rob Napier Jan 05 '16 at 15:03
  • The third party framework in this case is GoogleMobileAds.framework you mean that i should create a an empty framework project and put the framework there so it can act as a dependency for my A framework? until now what i dod is only place it in the A framework project path – Michael A Jan 05 '16 at 15:06
  • Edited. See if it's clearer. The key is not to embed the code more than once. – Rob Napier Jan 05 '16 at 15:53
  • tried what you say - first i am unable to drag GMA.framework directly to the framework target "Target Dependencies" section so what i did is create new framework target and link the GMA.framework to this target - "test" target. next i added the "text" target as a dependency to the framework project but sadly i still get the same error of undefined symbols. can it be that dependency simply define build sequence and not necessarily link the dependency to the project? – Michael A Jan 06 '16 at 10:13
  • 1
    While this work, but only for open source, when it build the compiler still try to include that framework into the current one, is there anyway to fix? – Tj3n Oct 20 '16 at 03:44