I am developing an app for IOS,and I have to use some framework.
as you know Cocoa pods and Carthage are dependancy manager for iOS and mac OS
my question is "why we have to use dependancy manager?, instead of using dependancy manager just clone that project[was written by other programmer and can be used as framework] and drag and drop to your project ??"
Thanks for your answers
Few things that you need to think about is:
Updating your dependencies when new versions came out.
Updating dependencies for multiple platforms.
Interdependent frameworks and different framework versions for dependant frameworks.
Basically, time that you will spend on maintaining dependancies for your project will grow as your project grows. Dependancy managers allow you to avoid all this unnecessary and boring work.
There are a lot of other reasons to use DM instead of just importing frameworks. More about you can find here. And here.
At some point you might want to use 3rd party code to get extra features or something, you can copy the source code but how you will update it in the future? keep coping it again!!
Also some of your 3rd party code might depend on other 3rd part code, and if you copied it twice, you will get duplicate symbols.
Dependency managers handle all this for you.
My advice is to use Carthage or submodules, but do not use CocoPods, anything that touches the project file is not a good practice with Apple.
Why Libraries are Your Friend
While you aren’t strictly required to use third-party libraries or
frameworks, they can definitely save you a lot of time and let you
focus on polishing your app instead of typing out countless lines of
code that you simply don’t need to write.
You can use third-party frameworks and libraries without a dependency
manager too, and you can get hands-on tutorials about them right here
on this site. For example, there’s our Alamofire tutorial, and our
SwiftyJSON tutorial.
Without a dependency manager, you simply add each library’s code to
your project manually. However, this approach has several
disadvantages:
Updating a library to a new version can be difficult, especially if several libraries must be updated together because one depends on
another.
Including a library in your project makes it tempting to make local changes to the code, making it harder to update to a newer version
later.
Determining the current versions of libraries used in your app can be hard to do, especially if you don’t proactively keep track of them.
Finding new libraries can be difficult without a central location to see all the available libraries.
CocoaPods helps you overcome all of these issues and more. It fetches library code, resolves dependencies between libraries, helps
you search for and discover new libraries, and even sets up the right
environment to build your project with minimum hassle.
Courtesy
https://www.raywenderlich.com/97014/use-cocoapods-with-swift
Related
I think I just must be stupid.
I'm having a lot trouble understanding very basic things concerning frameworks in Xcode/iOs/Swift. While I've certainly gotten some things to work, I've gotten more and more confused about what I'm actually doing. And the documentation on the web just confuses me more.
When I see discussions about how to import particular frameworks (e.g. https://github.com/danielgindi/Charts is the library I'm playing with, but I've seen this pattern repeated in other libraries) they seem to always tell me include the Xcode project file as a child project of my project, in addition to linking things as an embedded binary. This confuses me. Is it not possible to link an already compiled framework to my project without including all the source code of the project?
That is, can't I just take a library.framework file, and add it to my embedded libraries list and be done with it?
In the frameworks I've played with (again https://github.com/danielgindi/Charts is my primary example, but this is true in many others I've played with) I can't seem to use the framework without Carthage or CocoaPods. For me at this stage, that is just confusing... I accept that they are useful tools to automate a difficult process, but I'd really like to understand what that process actually is before I let a tool automate it for me. As I search the web I just seem to always be led back to these tools as being the correct way to do things.
So here are my questions.
If I find a framework library on the web... do I need its source code or can I somehow just link to a compiled version of the framework?
In my reading, it seems that libraries made with Swift are somehow second-class citizens because Swift is a newer thing. Is that still the case? (The articles I read about this seems to date from 2014-2015).
Is there are good place to understand how Apple expects me to add a framework to a project, without using CocoaPods or Carthage?
No need to add source code. Just add the framework to Target ->
General -> Linked Framework and Libraries -> Tap on + and select
your framework.
In my opinion, many new libraries are being written is Swift. So you won't be left behind for using swift.
Apple has documentation about adding frameworks to XCode. But I would suggest to use Cocoapods , as its easy to manage libraries.
Cheers :)
I know, there are so many same questions but I didn't get answer for my requirement.
First time I am creating framework. I have created test framework using Raywenderlich example. But my requirement is little bit different. I used so many different frameworks and also used SQLCipher in my project. Now, I want to convert this project into framework. I followed all the steps but the problem is occur when I am trying to build. Getting an error for SQLCypher because I didn’t add to my framework to avoid conflicts. Finally, I have added SQLCypher library to create build without error and it worked but now I am getting linker error when I am using that framework to test in testProject. I didn’t find any example with third parties. Please help me to solve this issue.
I had the same issue.
One solution is to change all method names of other frameworks or libs, but some lib is not open source.
Another solution is work for me which is to use cocoapods. But the user
who wants to use your framework will be forced using cocoapods, depending iOS 8.0 or above, depending the same version of 3rd libs. I have nothing to do with this restriction.
Seems the best way is do not depend 3rd libs in a framework.
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.
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.
I am writing an iOS library which depends on some other open-source libraries. Apparently it is not possible to have two classes with the same name, so it is possible that the library compiles, and a project that potentially could use it compiles as well, but they do not work well together (at the linking phase).
The library is targeted at a large audience, so I can not make any assumptions on whether these developers will be importing the same libraries or not, or if they might be using a different, incompatible version of the same libraries.
I have been looking around but couldn't find any clear solution to my problem (maybe there isn't). So far I am thinking of these options:
Inform the users that X libraries are already included in the project, so they do not include them as well. This means they can not use a different version of X libraries.
As a refined version of the first one, use CocoaPods, so dependencies are resolved automatically. Still has the disadvantage that two versions of the library can not coexist.
Import and rename all classes my library depends on, prefixing them, so the names don't conflict with the original ones. This is tedious work, but more importantly, has the disadvantage that I would not be able to pull/push code from/to the original library, as the code would change too much. Still seems to me the best option from the user perspective.
Can you think of a better idea? I'm pretty new to library projects, so maybe there is something obvious I am missing.
We're still not decided whether to distribute in binary or source code form. If there is a reason to choose one or another I would also like to hear your opinion.
When I was faced with this problem I choose your third option and prefixed the dependent classes within my library. The reason you might want to consider doing this rather than relying on the user to import the others would be that you can guarantee compatibility and you don't have to worry about versions of who you depend on.
First point -
Inform the users that X libraries are already included in the project,
so they do not include them as well
so you have a static library Foolib.a, it has a 3rd party dependency Barlib.a, in order for Foolib to build, Foolib's HEADER_SEARCH_PATHS must be set to the path of Barlib's public headers. No more.
If you are distributing your source code you can use CocoaPods (this is a good way to go), or you can add Barlib's repository as a git submodule (or whatever for your choice of VCS) of your repository and hard code the HEADER_SEARCH_PATHS to that path, or you can require that your user grabs their own Barlib and manually edits HEADER_SEARCH_PATHS to the correct path (if you go the CocoaPods or submodule route the user can easily do this as well, so has more options).
Nothing from Barlib is 'in' your project.
On the other hand, if you are distributing a binary for your user to link into their app you must specify in your instructions that Foolib requires Barlib to be linked into the app. Instructions for how to get hold of Barlib would be nice.
Nothing from Barlib is 'in' your project or compiled into your library.
Second Point -
use CocoaPods, so dependencies are resolved automatically. Still has
the disadvantage that two versions of the library can not coexist
Two versions of the same library in one App is impossible, but the situation where the end user already requires Barlib 3.0, wants to use your Foolib, but Foolib requires Barlib 4.0 doesn't have to ever arise - It is up to you the developer. You can be generous and support multiple versions of Barlib (i.e. all Foolib needs to work is a Barlib1.0, Barlib2.0, Barlib3.0 OR Barlib4.0 linked into the app - similar to writing an app that supports iOS5 and iOS6) or, you can be opinionated and require a specific version, and if the user is already requiring a different version of Barlib, tough luck, they will have to change their code if they want to use your library.
Third point -
Import and rename all classes my library depends on, prefixing them,
so the names don't conflict with the original one
This is just too terrible for me to consider at the moment. Sorry.
Nothing from Barlib is ever 'in' your project or compiled into your library. You don't distribute any copy of Barlib - either linked into your binary or as source code.