iOS frameworks interoperability - ios

I am currently refactoring an iOS app which contains massive amount of classes, and as requested, I made few CocoaTouch frameworks (and again, as requested, not static libraries) to contain these classes based on their purpose (models, requests, etc.).
However, framework A contains class, that I need to use in framework B, and I'd like to ask if anyone knows how to "connect" the two frameworks? Like some sort of chaining, maybe?

I guess by connecting frameworks you mean you want to use classes from framework A in framework B.
Step 1: Target Dependencies
I assume your framework targets belong to the same project. In this case you need to make sure that framework A is a target dependency of framework B. This way framework A will be build before framework B.
Step 2: Linking
The linker needs to know where he can find the symbols for framework A if you want to use them in framework B. Therefore, add framework A in the Link Binary with Libraries build phase of framework B.
You should now be able to use classes of framework A in framework B. You also need to add framework B as target dependency to your app target, link both frameworks with the app, and also add both frameworks as Embedded Binaries to the corresponding Build Phase.

Related

Xcode: Linking external framework in a framework project

I am creating a framework (say My.framework) which will make use of an external framework (say External.framework).
I don't want to include External.framework in My.framework, since it increases my framework's binary size.
How do i build My.framework, so that the host project works only if the External.framework is present?
You can create workspace, with your App, your framework and external framework.
In your framework in target general tab add external framework to Linked Frameworks and Libraries.
In project two if you include your framework but without external framework, compiler will signal error.

Can I make iOS all-in-one framework? or include private static library into my framework?

I'm a novice on XCode and I'm making an iOS Framework with Swift2, including 3rd party libraries(*.a) and frameworks.
I want to provide it as API to others, but I also want to hide the 3rd party libs and frameworks files from my framework distribution files because they are private.
Therefore I just want to open API interfaces and classes I defined.
Is it possible? How to configure my build options?
You can do that but there are some things you need to consider:
You cannot embed one framework into another one. That means if you do not have the sources to a particular framework you have to ship it alongside your own framework. If you have the sources you may consider compiling them into your framework directly.
Depending on the sources that you use in the framework you might have to do some post processing of the framework to obfuscate private headers etc. For example, if you use Objective-C or C code alongside Swift you definitely need to do some post processing of your *.framework file to hide any API that you want to keep private.
If you use Swift code in your framework please be aware that your framework can only be used by someone with the same Swift compiler version due to the absence of an ABI. That means binaries produced by one compiler version have a high likelihood of being incompatible to a newer version of the compiler.
Static linked libraries can be linked and therefore "merged" into your framework binary directly. You just need to make sure that you have a compatible binary for the architecture you want to target, e.g., you cannot use a static linked library that was build for simulator and link it against your framework that you want to build for the actual iOS device.
If you use Swift in your framework, the users of your framework need to include the Swift dylib libraries in their app bundle - either by using Swift in the app or by enabling the Embedded Content Contains Swift Code build setting.

How to build an iOS Framework with a dependency on another without creating an Umbrella Framework

I am trying to streamline my development by creating some re-usable Frameworks which incorporate features I commonly re-use in multiple projects.
However, having setup one of my Frameworks I have encountered a problem, the classes have a dependency on the Firebase framework. Having read the Apple docs it's not recommended to create an Umbrella Framework (one which embeds another) especially if you do not have ownership of the embedded Framework (which I do not).
So the question is:
How can I create a Framework project which allows me to build the Framework without including the dependencies which would create an Umbrella Framework. I presume this is what people like Firebase do because when you add their Framework there are others you have to add to your project as well. I can't quite see how you would configure a project to allow you to build the Framework without errors but not include the dependencies.
For reference I am using the latest Xcode and need to support iOS 8 and above.
Thanks in advance for any thoughts / suggestions on this
For the benefit of anyone who is struggling with the same issue, the answer is much simpler than I had anticipated.
The Frameworks are linked dynamically and simply adding a Framework to the project for your own framework will not cause it to be embedded in the output file and therefore not generate an Umbrella Framework. You don't actually need to do anything. Any Frameworks that are required by your own Framework can be included in your project so that you can compile your own Framework, and will also need to be included in any projects that utilise your Framework.

Use third party framework which is embedded in dynamic framework

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 :)
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.

iOS framework and separate project have the same framework dependencies

I am creating a framework in Xcode for my iOS app which contains a large set of common classes which are used amongst several projects. Some of these classes have dependencies on other frameworks. However, there are also classes in other projects where I want to use this framework, which share some of the same framework dependencies.
To try simplify with an example:
Framework A: has classes which require Framework B
Project 1: includes Framework A, but has a class which requires Framework B.
I am currently including Framework B in Framework A so that my code will compile. There are two problems:
Once I do this, I can't include Framework B in Project 1, because there is now a duplication of classes.
It sounds like I'm creating an umbrella framework, which is usually discouraged.
Is there a way I can build Framework A in a way that says: "trust these frameworks will be included in any projects that use you, and don't include them yourself"?

Resources