xcode how to develop with frameworks - ios

Thanks for spending time reading my question.
I've been working as an iOS developer for more than 2 years and today I still feel shame because I don't know how to deal with frameworks. I've build some projects using my own frameworks, but I've never understood exactly what's the best practice doing this.
Lets see the following example:
Project -> FrameworkA -> AFNetworking - Charts - FMDB - more
So, I have a big FrameworkA with mostly all the app behavior and then a small project referencing this FrameworkA and customizing just icons, texts and images. I use to manage dependencies with CocoaPods and I would like to use it with FrameworkA. By this I could reference external libraries easily, but it seems it doesn't work for frameworks, only for projects. So, my questions is: how can I add AFNetworking, Charts, FMDB, etc to my FrameworkA and then reference the framework form my project?
I appreciate if you can give me some idea using CocoaPods or any other dependency manager. I don't like the old way by doing this manually.
I hope my case is clear.
Thanks!

It sounds like you are asking how to embed external frameworks such as AFNetworking into a framework you are developing, and then use that framework in your app.
This is what's known as embedded frameworks where one framework is stored within another. Generally speaking it's not a great idea and should be avoided because it can cause version clash issues.
The way I'd recommend doing this is to use CocoaPods or Carthage to link the external frameworks (AFNetworking, etc) into your framework project. But do to try to embedded them.
Then in your app project, again use CocoaPods or Carthage to link in your framework (you won't need to link the external ones unless you are directly using them in the app code). Then add the necessary build steps to copy both your framework file and all the external framework files to the finished app's framework directory.

Related

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.

iOS Frameworks, embed another framework or library?

So in Xcode 6, we finally have the possibility to create and distribute our own libraries as Frameworks (as opposed to Static Libraries before).
The question, is it possible to "embed" another framework or library directly inside the framework rather than ask the end user to link them?
The reason is as follow: Creating and distributing frameworks for other people often requires them to manually add whichever framework we link against.
That's fine when these libraries are a default ones that can be added straight from Xcode, but when we need to link against other public frameworks.
One example would be if the framework uses AWS as a backend, it's a bit overkill to ask developers to also download a specific version of their SDK and link against specific bits that are required. And it becomes more overkill when we need others for performance logging or more.
On OSX, there is the possibility to use Umbrella Frameworks, but it's undocumented on iOS.
Thank you.
Recently done this myself on iOS, unfortunately any framework that has sub-frameworks must also be linked to in the project the parent framework gets used in.
Create the framework as per normal, and include the other frameworks under that framework (it should be an aggregate target).
Then build the parent framework, and link this into the main project. Attempt to compile and it will mention that it needs it sub-frameworks also linked. You can then link these sub-frameworks in addition and it will compile.
This is unfortunately a limitation of Xcode/iOS as it currently stands.

iOS dependency management and packaging

I'm completely new to iOS development and coming from an Android background. I was starting to look at what alternatives are out there for dependency management in iOS and found out that CocoaPods seems to be the most prevalent option.
After reading a lot of links about this topic I'm kinda at a loss and wondering what is the usual way dependencies are handled in iOS.
I have two questions:
1) What would the equivalent of using gradle to generate library (.aar) projects be in iOS? If there's any equivalent option. From what I've seen one can wrap static libraries and headers into frameworks and these can be used in other apps, is this the standard way to do it?
2) If (1) is correct, does CocoaPods offer a mechanism to add frameworks as dependencies?
I don't have a Android background but from what I understand of .aar files CocoaPods does something very similar. CocoaPods uses .podspec files (described here) to generate static libraries (and soon dynamic frameworks which are new in iOS 8) that are then linked into your project.
A podspec can define source files, assets, libraries, or frameworks that a source vendors for linking into your application. So yes it does support adding frameworks as dependencies, although until iOS 8 frameworks were not supported at all on iOS.
As far as the 'standard' way to do it, I think that's based on opinion. There are a few general ways to include dependencies you can choose from.
Drag files, frameworks, and whatever else you need into your project manually. Updating these is more difficult and that also means you have to configure your .xcodeproj depending on what features that library needs (such as ARC)
Drag a provided .xcodeproj into your project, and link the relevant target from the given project. This can be nice if the library provides a project that can build a framework or static library, in this case you'd pull in that library but their project would handle custom compiler flags.
Do either of the above while including them as git submodules. Assuming nothing massive changes in the project this helps a lot with updating your dependencies.
Use CocoaPods. CocoaPods will handle all the custom linking and updates based on semantic versioning (usually).
Use Carthage. Carthage is an in- between CocoaPods and the .xcodeproj solution. It will download code based on semantic versions defined by git tags, then you drag the generated frameworks into your project.
All of these options have pros and cons and the decision normally comes down to how you feel about the control you have over the inclusion of the library, and how automated you want it to be.
I do not have android nor iOS background however I've been developing a CI tool for both platforms and here are the answers
As You mentioned this a framework and pods (libraries) from cocoapods are distributed that way. For instance, have a look at Apphance. When spec is clicked it's visible that this library will be accessible as a Apphance-Production.framework.
You add pods to Podfile and download them with pod install command. This command will made classes from Apphance accessible from the code. Some people do commit downloaded pods, other not (it's like adding jars or aars to source control).

iOS Framework build: what is the best practice to link with third-party libraries?

I'm build a Framework for iOS and my framework has AFNetworking as dependency.
So what is the best practice to include AFNetworing? Reading other posts (specially this question here) i came up with three options:
Copy all the .h.m files from AFNetworing in to my project and compile my framework with it. But according to this, it will possible cause a situation where some third part developer using my Framework are already using AFNetworking and will get a compile-time error that some class is declared twice.
Use CocoaPods and link AFNetworking to my Framework. This is causing this error: -lPods is not an object file (not allowed in a library).
Build something like the Aeris SDK where the third part developer using my Framework will be responsibly to add AFNetworking to their project.
I think that option 3 is the best but i don't know how to do that. How can i dev my framework calling AFNetworking classes/methods but do not include on the final framework product?
Thanks!
That's a very bad practice to use third party library in you library.
Ideally you should avoid doing that.
But if you really need it, you can define and add prefixes to class names.
Refer this article Avoiding dependency collisions in iOS static library managed by CocoaPods
Ok. I decided to go with the option 3.
A just added all the header files from any third-party lib to the my framework project (you can also add the .m files but not include them on the static library target).
And a i also documented everything, so developers using my framework will know what are the dependencies and how to include/install them on their own projects (including third-party lib versions, CocoaPods support, etc).
I decided not to go with option 1 because that will cause some situations where a project will have two copies of the same lib compiled on the final app. Even if a change the namespace for the libs on my framework code (to prevent "duplicated symbols" errors) that will still cause some other possible problems like an APP with larger size, possible bugs related to two or more instances of the same lib running together, etc...

Working with libraries in Xcode (i.e. ImageMagick, AdMob) include in project or link?

(This may have been asked many times before but I'm not seeing it in the suggested questions/search)
Assuming I have 3rd party code libraries like ImageMagick and AdMob which I may use in multiple iOS projects, is it "better" to link to them or to include them in the project?
I'm using XCode with git. In one project I have included them so they are all under source control. In another project they are linked and I am getting "?" (question mark) icons next to all the library files. Confusing.
My honest suggestion for using 3rd party libraries would be to use CocoaPods for as many as you can get your hands on. Which there is a good chance all would be available.
Reasons why CocoaPod inclusion is better:
Easy to add and remove from project
Automatic linkage to your project
Easy to update after including
Drawbacks to CocoaPod use:
Doesn't help you if your library isn't included
You don't want to use the newly created xcworkspace instead of xcodeproj
The reasons not to use them are pretty weak, and I will admit to be biased in favor of them. I have had to work with lots of static libraries and frameworks, most of which are created in house. CocoaPods has made sharing, maintaining, and installing libraries a piece of cake. So please consider using them in your project.
If CocoaPods aren't your thing or not an option, linking against the library or framework is probably second best. If you drag and drop into your project (while easy) makes updating later kind of a pain. Dynamic linking allows you to swap them out from the file directory without having to change anything in your Xcode project. It requires a bit more finesse to get set up, but ultimately will be better for the long haul. IMO anyway.

Resources