Creating static library which depends on other static library (RestKit) - ios

I followed the following tutorial to create a static library:
https://github.com/jverkoey/iOS-Framework/#developing-the-framework-as-a-dependent-project
It all works until I try to incorporate the RestKit into my static library. There I am completely lost. Am I supposed to include the RestKit library into my static library or only in the App which will use my library?
If I don't include RestKit in my library, I can't compile it as it depends on another library (RestKit) so what would be workaround for this?
I tried to look everywhere but haven't found a good step by step tutorial to create a static library which itself depends on other static libraries.

What I did to get this working was to add RestKit to my static library using their git-submodule instructions here. Then I performed the exact same steps on the projects that were going to use my static library EXCEPT:
I did not add RestKit to the "Target Dependency" section of the Build Phases
I did not add the libRestKit.a to the "Link Binary With Libraries" section. All other references still needed to be added.
I was then able to reference RestKit in both my static library and my iOS project.
COCOAPODS MEGA HACK
I was able to get this working with cocoa pods, but it will only work if this is your only cocoapods project. I started with all of my projects in a single workspace. Then I had my single podfile install RestKit to my static library and all projects that were going to reference my static library. Then for each project that I wanted to reference my static library I removed the pod reference under "Linked Frameworks and Libraries". Everything was then working as expected.
As you can expect, this would probably break all other pod references (unless you managed them all through that one static library), but it does seem to work.

Shorty after asking the question I finally managed to get it working here the steps if someone has a similar problem:
Create an actual app as explained int this section. After adding your library add all the other libraries you use to the application. (In my case it was the RestKit framework, add it as a submodule and not with cocoapods as with cocoa pods it didn't manage to get it to work properly).
After adding all your libraries, follow the third party libraries instruction for modification for the application and make the same modification for your static library.
e.g. for Restkit I had to add
-ObjC -all_load
to the Other Linker Flags and add
"$(BUILT_PRODUCTS_DIR)/../../Headers"
to the Header Search Path inside my static library.
I still couldn't build as the <RestKit/Restkit.h> wasn't found, so I needed to change the build order of the frameworks to assure that Restkit was built before my library.
This is done inside the edit Scheme of the build menu. Make sure that all the dependent libraries are on top of your library (if your static library or the dependent libraries aren't already in there add them with the '+')
Afterward everything worked for me. I am not sure if this is the best method to do it or if it would be better to include the third party library inside your statistic library.
Update I still run into problems when trying to build my library, if someone has a better solution or can shed some light on how to create a static framework which depends on other frameworks I would appreciate it.

Related

How to use cocoapods in xamarin.ios

I would like to make use of couple of cocoapods in my xamarin.ios project.
But I couldn't find those cocoapods in Nuget which is package manager for Xamarin.
I heard we can compile a xcode project into a static library ... that is .a file and use it in xamarin.
But I am getting confused on how to convert the pods into a static library or something so that I can use those pods in my xamarin.
You cannot take the Pod directly and create a static library but you can although create a static library from the Pod project which already contains your pod. But to be honest the best solution will be getting the source code of the project and create the static library from there. Most of the Pods out there are open source so grabbing the source code from github should not be a problem.
Once you have the source code follow this example to show you how to create static libraries from there.
Once you have created the static library you just need to follow this tutorial to create a Binding library that can be used in Xamarin.
Unfortunately AFAK there's not support yet for Swift libraries to create binding libraries so this will only work with objective-c code.

iOS8 framework library linking WITHOUT Pods

Imagine the following scenario;
I'm developing a cocoa touch framework that requires SomeLibrary (e.g. AFNetworking). My framework is going to be included into someone's project that might require SomeLibrary as well.
How do I accomplish this without running into these nasty duplicate warnings when I include AFNetworking into my framework directly (either via source code or Cocoapods)?
I've tried it with Cocoapods on both projects (my framework, and a test project that includes my framework), but that results in duplicate code warnings as well.
When I don't add AFNetworking into my framework development project, the compiler can't find the required files, which is why I can't build it. I've tried with including AFNetworking's source code directly into the main project, and using the pod, but in both cases the AFNetworking/AFNetworking.h import in the framework project fails.
How can I do this without making a pod out my framework (which isn't really an option)?
I've found this related answer, but I don't know what search path to set for the framework project in order to find a library of the master project;
https://stackoverflow.com/a/23123725/1069487
Any help would be highly appreciated!
You will have to build your framework linked against static library.
You build AFNetworking as a static library (that will give you a .a file as AFNetworking.a)
You build your framework that link against your static library. But be aware that the library won't be embedded in your framework (there is no way to include static library into framework on iOS). Your framework is able to use AFNetworking API because it is linked against it.
any project that use your framework and use AFNetworking methods of your framework need to link with the static library AFNetworking.a that you should provide as a standalone file beside your framework.
See iOS-Framework here for more details : https://github.com/jverkoey/iOS-Framework

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

Can you make a Podspec with conditional dependencies?

I want to know if you can define dependencies on an static lib in a podspec depending on the type of the Target that the Pods project is going to be linked to.
I need to be able to NOT add a dependency to an static lib if the target project is itself an static lib.
Why I need this?
I've built a podspec for cocos2d-iphone v3 and using it in a personal pet project. Works perfectly when you use it as a dependency for an executable. Unfortunately it doesn't works well the way I've organiced my project:
It's a multiplatform project app consisting in two xcode projects for the ios and osx executables. Both link to an static library with shared code (another xcode project). I've made the cocos2d a dependency for that last static library.
Unfortunately, cocos2d has a dependency over lib z, which is also static. As you can't link two static libraries the link phase fails. The error message is as follows:
file: -lz is not an object file (not allowed in a library)
It's easy to remove that dependency but I would prefer the process to be more easier for the end user.
My approach to solve this problem would be add a conditional in the podspec so the lib z only is added if the project is not an static library. I guess it can be done with pre_install hooks, but they are discouraged by the cocoapods team.
Is there any other way to accomplish this?

Avoiding header conflicts when creating and depoying Static Libraries in iOS

I have created a static library in iOS where I have certain common functionality for my projects. I used the instructions for the iOS Universal Framework and everything works great.
I have a module in the static library that requires AFNetworking. So I installed the cocoapods, and included it in my static library
However, when I include my static library into another project that also needs AFNetworking, and I run the project, I get a duplicate symbol error for all the common classes.
What is the best approach to avoid a conflict like this?
The best approach is not to include any 3rd-party libraries / frameworks inside your framework.
Here's Apple reference regarding "How to build your own framework". There are a lot of guidelines that will help to build a good framework that will not cause any errors if you'll link it to any project.
AFNetworking is a framework that is application specific, so you should not include it into your framework. You may weakly link your framework to AFNetworking, but you should avoid strongly linking it.
Here's resource regarding weak linking.
For example, if you are using 3rd-party library, you should specify that your framework require user to add dependencies in order to use it.
Here's an example how AFNetworking does it.
Also, check this framework, and it's requirements regarding dependencies in its specification.
The best way to do this (in my opinion) is to underscore the class names to keep them unique.
So let's say your library is called XYLibrary. It will have a bunch of AFNetworking files like AFNetworking.h and AFNetworking.m. Rename those to XY_AFNetworking.h and XY_AFNetworking.m. This should hopefully keep them unique from other instances of that library in another project.
You should do this for any other 3rd party libraries as well.

Resources