Can a Objective C Framework/Static Library consist of third party framework - ios

This is just an informational question, I have been examining several ways to make frameworks in iOS.
I made
Swift Pure frameworks:- There I got to know that, you have to include the xcodeproject to the application project to use the .framework included in .xocdeproject. So I thought this is not the secure way to giving code to third party and I also I did not find ways to include the third party frameworks to my own framework.
Objective Static Libraries:-
In this type libraries, the system is generated a .a file which is secure and the person gonna use does not know the implementation part however found out that if I want to include a third party framework to this, I will have to ask the end user to include that third party project to end application to compile it which will show the end user what all dependancies I have, which I don't want.
My issue is I wan to make a Framework which will consist of all the third party frameworks however, they would be hidden from end user although the codes from them can still be used by end user as required however, end user should not see them listing in my framework.
Is there a way out?
I have gone through many links and found out that many have this doubt as well
Like
Adding FacebookSDK.framework into my own Static library
In this post, one person is asked to get all header files and the framework file and then add that to static libraries to build to add the framework itself, I tried that too without success.

Do not do that.
There is literally no good outcome of what you're trying to do. This is very confusing and couples your library API with a different library's API, forcing the user to stick with your version of the 3rd party lib.
If the user will want to use a newer version of the 3rd party dependency, he won't be able to, because it will result in duplicate symbols.
You can't find any information about such practice on the internet, because nobody does this.
If you want to distribute an already compiled library, there's no other way than just compile all 3rd party code with it, without exposing the header files.
There's one very big important thing left: you have to make sure that users of your SDK will not end up with duplicate symbols if they also use the 3rd party library!
More here...
And here...

Related

Can a Framework Collision happen in a Swift SDK?

I am trying to develop a library, and then distribute it later as an SDK. In that library I am thinking of using a third party library.
What I am afraid of is if one of my users also include that same third party library. Would it still build? Otherwise, is there a way around this issue?
Note that I cannot use CocaoPods.
Yes, this can and will collide. You must not include a third-party library inside your library. You must have the app link both your library and your dependencies at the app layer. Tools like CocoaPods, Carthage, and SwiftPM simplify this. If you cannot use those, then you must provide instructions to your users of what libraries they must link.

Multiple frameworks and common library

Using iOS 8, Xcode 6.
Let's say I have 2 dynamic frameworks, frameworkA and frameworkB and they are both dependent on libC. In addition, I have an app that uses both frameworkA and frameworkB. My original thought was to make frameworkA and frameworkB umbrella frameworks and libC a subframework. However, Apple advises against umbrella framework and this post describes why umbrella framework is a bad idea due to potential linker conflict issue.
My second option is to use cocoapods (still new to this so a bit fuzzy on details) to use libC as a pod which then gets compiled into frameworkA and frameworkB. However, it occurred to me that both frameworks still has its own copy of the libC. Since the app uses both frameworks, will this result in a linker conflict issue as well? Is there a better way to solve this problem?
UPDATE
#Rob The projects I work on do require complex dependency management but I kept the problem domain simple in the question to try to better understand how and if using cocoapods can help solve the linker conflict issue with umbrella frameworks. I work with a team of developers who write libraries and can depend on each other's base libraries that provide versioned common APIs. We are required to package and deliver as few libraries as possible to a different organization that is building an app with our libraries and one of their key requirement is that we deliver a dynamic framework.
The best way to solve most problems is to put all the code in a project and compile it. When you have specialized problems that make that problematic, then you should look at other solutions, such as static libraries, and finally frameworks.
Static libraries can make sense if you have a code base that has pieces which require different build requirements. If all the pieces have the same build settings, then just "add files" them into your project from a "common" directory and build your project. Static libraries can be attractive if your build times are very significant and some pieces never change and you want to be able to "clean" without rebuilding those parts. But wait until you start having that problem before you go making complicated multi-package projects.
If you sell closed-source libraries, then frameworks are very attractive. You should strongly avoid adding third-party dependencies for the reasons you note. If you must, the best way is to help your customers package all the pieces as frameworks and have them link everything at the end. But that adds a lot of annoyance; so make sure you really need that third-party piece.
You might also consider frameworks if you have a very large piece of reusable code that has its own lifecycle separate from the main products. But again, keep it simple. Avoid third party stuff inside of it, and if you must have third party stuff, then have the consumers link it at the end.
(This isn't a new solution, BTW. When you use curl, if you want SSL, you need to also download and build OpenSSL and link them together yourself. Curl doesn't come with OpenSSL built in.)
But in the vast majority of cases, this is all overkill. Don't jump to frameworks. Don't jump to libraries. Just put all the code in the project and compile it. 90% of your problems will evaporate. iOS projects in particular just aren't that big usually. What problem is a framework solving?
If you have a lot of code that your organization uses repeatedly in lots of products, then I have heard many teams have good luck using internal CocoaPods to manage that. But that's just to simplify checking the code out. It still all goes into a project and you compile it together into one binary; no frameworks needed. Dynamic frameworks are a nice feature in for certain kinds of problems that were really painful before. But, for most situations, they're just complexity looking for a problem.
(If you have one of those specialized problems, edit your question and I'm happy to discuss further how you might approach it.)
EDIT: (You fall into that "specialized problem," so let's talk about it. I did, too, for many years inside of a large multi-team Mac and iOS dev environment. And we tried just about every different solution, including Frameworks. They're only new on iOS.)
Within an org like you describe, I would strongly recommend packaging each dependency as its own framework (AFNetworking, JSONKit, etc) and each of your pieces as a framework, and then have the app devs link all of them together at the end. In this way, it is identical to other dynamic libraries (libcurl, openssl, etc.) which require the app dev to link everything together.
In no case should dynamic frameworks include other frameworks that could otherwise be required (i.e. frameworks should never package "third party" stuff). That will explode. You cannot make that not explode. You'll either have bloat, build conflicts, or runtime conflicts. It's like merge conflicts. There's a point at which a developer has to make a choice. App-level linking is making that choice.
Making components over-dependent on other components is the source of decades of trouble, from Windows DLL Hell to iOS apps with competing crash handlers. All the best component systems look like Legos, where the end user assembles small pieces that have minimal dependencies. As much as possible, make your internal frameworks rely on nothing but Cocoa. This has some tangible design influences:
Avoid directly requiring logging or analytic engines. Provide a delegate interface that can be adapted to the engines of the caller.
Avoid trivial categories (methods that save just a few lines of code). Just write the code directly.
Avoid adding framework dependencies that aren't buying you a lot. Don't add AFNetworking just to save a few lines of code over NSURLConnection. Of course if you're heavily relying on the features of another framework, that's different. But as a framework developer your threshold should be quite high before requiring another framework.
Strongly avoid being clever in the build or version control. I've seen too many cases where people want to make everything "automatic" for the app-level developer, and so make the system really complicated. Just say "you need to link this and import this and put this in your app delegate startup." Don't create complicated build and version control systems to save 2 minutes on the first build or two lines of initialization logic. These things blow up and waste hours to work around. Don't get clever with +load magic. Just make it clear and consistent.
And of course, good luck. Supporting other devs is always an interesting challenge.

Use two versions of the same library

I'm working in a iOS project that includes a static library created by another company.
The library include an old version of AFNeworking and I don't have any source files.
Now i need to use a more recent (and less bugged) version of afneworking, but i cannot include the same class twice in the project (of course) because all the "duplicate symbols".
I understand that it's impossible replacing the version included in the library, but how can i include another version along the old one?
There is a (easy) way to refactor the entire framework before include in my project?
thanks
You'll have to repackage the static library to remove the embedded AFNetworking files.
Unpack the library with:
$ ar x libwhatever.a
And re-package it, including all files except the AFNetworking object files:
$ ar cr libwhatever.a file1.o ... fileN.o
You will then have to link your executable with the new AFNetworking static library and hope that there haven't been API changes which will break the code in libwhatever.a. If there are then I doubt there is much you can do.
I'm afraid this isn't easy to do. Very few environments allow you to link against two separate versions of the same framework at the same time, and Xcode / iOS is not one of them.
As I see it, you have three options:
1) Link against their library and use the same version of AFNetworking they use.
2) Link against their library, and manually load the newer version of AFNetworking and pull symbols from it. Be warned: this will get ugly fast and future maintainers will wonder what you were smoking.
3) Get them to update their library.
On a side note, I don't know the circumstances here, but in general they should be providing you with sources. It's a very backwards practice to provide only a static (static!) library and no way to know what it's doing inside. You'll have to sign a software license agreement and whatnot to protect their interests.
The best and most proper way of handling this would be to contact the the creator of the static library and get them to resolve the situation. They could resolve it either by updating the embedded version of AFNetworking, removing their dependence on AFNetworking, or adding a prefix for their embedded copy of AFNetworking. The last one is probably a good idea anyway when a third party library embeds a different library, because otherwise it would be impossible to use two libraries simultaneously that both include the same third party library.
You could also refactor the copy of AFNetworking that you include yourself to change the names of classes to have a prefix, although this should be unnecessary, as the static library vendor should have done this themselves already.
Lastly, you could find a different library that accomplishes the same thing as your current one but that doesn't embed AFNetworking.

Renaming external 3rd party library classes in my library

I want to add add 3rd part library to my library (which will be used by other developers), so if I have for example this class SBJson do I prefix it with my two letter prefix to be EXSBJson also I saw somewhere somebody is using underscore EX_SBJson. What is the naming convention/style in this case?.
There is no general convention, but we have used the following approaches:
Use the same prefix as the library (so if we develop XYFunctionality, we would name it XYSBJson). A lot of source projects use this approach (e.g. Dropbox)
Talk to other devs, if possible. In most cases, it is enough to distribute the library separately from 3rd party libs (so we ship a .a binary file and a working source project of the 3rd party library so other devs can use it). This also allows other devs to upgrade the 3rd party library to get bugfixes as long as there aren't breaking API changes.
Btw. much of what SBJson does can also be done using NSJsonSerialization which comes with iOS 5+

Controlling export of third party symbols in an iOS / iPhone SDK

If you're building a commercial iOS SDK that will be included in other people's code and you have third party libraries that you have a license to, is there an effective way to simplify the library / framework structure by not exporting those 3rd party symbols in a static lib?
I appreciate I could instruct developers to check for overlapping symbols, but I'd like to minimize instructions. Ie, just want them to drop the lib into their project and off they go. I also do not want to export my third party symbols as they may change in later projects.
Unfortunately, there isn't a lot to be done here very easily. A static library is just a bunch of .o files glued together. There is no linker step to determine what pieces are actually needed between .o's. That's not done until the final link step (by your customer).
That said, there are some things you can think about:
First, whenever possible, avoid including sub-libraries inside of a static library. This is really dangerous if it's possible for the customer to have other copies of the same sub-library. Your situation seems to be difference since your sub-library is licensed, so the customer is unlikely to have multiple copies, but for example, you should never include a static copy of libcurl in your static library. You must ask the customer to link libcurl themselves, or else things will explode quite badly for them. (See Linking static libraries, that share another static library.) Again, this sounds like it may not apply to you, but keep it in mind if you have common open-source libraries in the mix.
An old-school solution for dealing with visibility is to glue together your compile units. This is a fancy way of saying "concatenate all your .c/.m files into one massive file and compile that." Any function you mark "static" will not be visible outside this compile unit, and so shouldn't be exported. This also happens to increase the possibility of compiler inlining and other optimizations (particularly without fancy link-time optimization) inside of your library.
See Symbol Exporting Strategies. You have several options:
marking symbols as static (probably not possible in this case since they come from a 3rd party)
Use an exported symbols list or an unexported symbols list
Set the visibility attribute of the symbol directly (again, probably not possible in this case)
Use -fvisibility command line option when compiling (probably your best bet here)
Use weak imports
Use a weak library
These are explained at the link above.

Resources