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"?
Related
I am trying to create a CocoaTouch Swift Framework which I can then distribute to 3rd parties for them to use, and I can build it and use it ok on my machine.
The issues arise when I give it to other people.
My framework uses C code, which I make available for use with Swift within my framework via a module.modulemap file as such:
And I am able to use such module in a Swift file, within the framework, ok, as such:
However, when I build the framework and give it to other people to use, their compiler complains that the Minzip module is missing with the message Missing required module 'Minizip'.
Having investigated, it seems like I'd have to make the users of my framework modify their Swift Compiler - Search Paths -> Import Paths the same way I have to do it to have my compiler find the module.modulemap.
Is there a way that I can build the framework so that I don't have to do this?
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.
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.
I'm trying to split my large Swift framework to many module frameworks so every module in my application will be independent in order to reuse on another apps.
Due to the fact that I have a big data like classes and libraries that shared with all of the modules I thought to create a core_framework contains share data and enforce the app to use this framework in order to enable use all the other frameworks (one or more)
I saw an example of FBSDK there is a core framework and other functionality frameworks : FBSDKCoreKit and FBSDKLoginKit
This is important to me that all the other frameworks will not contains the core framework for reasons of efficiency.
My question is - after creating the core framework what I have to do in my nodule framework so it's will recognize the core classes and functionality but will compile with out the core's files?
Thanks
When you split up a project into submodules, what you have to do is quite simple, though some details depend on how you partition your project.
Easiest case: 1 project with N targets
Say you only work on this one app and split it into modules. The easiest way is to add more Framework Targets to the project.
You then need to embed them in your app target. Make sure it's part of both "Embedded Binaries" and "Linked Frameworks and Libraries".
Now you have a new framework module.
Create a couple of them ("Core" and "Module 1", for example). Then:
In "Module 1"'s General project settings, add "Core" to "Linked Frameworks and Libraries". There's no embed option for frameworks, as they cannot include libraries, only the dependency on them.
In the app target, embed & link "Module 1".
That's all you need to set up.
I tried to diagram the embed and link settings so you see that only the app target contains the other frameworks:
Slightly more complex: multiple projects
The basic setup from above applies to all other variants: frameworks (modules) can depend on other frameworks, but they cannot ship with them. Only the application can finally resolve the binary file dependency.
If you split your project into multiple sub-projects, e.g. extracting deployable open source libraries for other people, then you have to make "Module 1" aware of "Core" in each project, linking to the "Core" module the same way as detailed above. What makes isolated Xcode projects a bit more complicated is: how does the "Module 1" project know about the Core.framework?
You could expose each module via Carthage and depend on one from the other,
you could use CocoaPods,
you could check out dependencies via git submodule.
The options above keep each module project autonomous. Dependencies are part of the directory tree of a module.
A bit less orderly:
You could create a Xcode workspace, drag all projects inside, then drag the Core.framework from the "Products" group of one project to the "Linked Libraries" list on another, or
drag the Core.framework file from the Finder onto the "Module 1" project (optionally selecting "Copy files if necessary" to put the resulting binary into the "Module 1" directory tree).
The above options can work, too, but they form assumptions about the location of files in the file system. The workspace approach should help to reduce problems with outdated framework binary files, though, as the workspace can help create formalize build dependencies from inter-project dependencies. Just like the app target depends on its framework targets, and like test targets depend on the app target to be compiled first.
Dealing with dynamic framework i am experiencing symbol conflicts errors which are best describe here: Symbol collusions with third party framework
The problem happens when third party framework is linked twice - in dynamic framework and in consumer project which use the framework and also import the third party framework as dependency
As i can see solutions for static frameworks which suggest removing classes from framework: Removing classes from static library or prefixing classes Prefix classes static framework i am looking for solution for dynamic framework which have diffrent structure.
How is listing classed performed in dynamic framework? what are the actual files which contain the classes which will be compiled at runtime including third party embedded frameworks?