Git submodule tutorial – Cocoapods might not be the solution.

Recently I’ve been in lots of discussions about git submodule Vs cocoapods, and I noticed that, unfortunately, lots of developers never tried submodules, like the normal flow nowadays is to just go directly to cocoapods. Lots of arguments on why cocoapods is better are actually something that git submodules also does very well, like “semantic versioning”. Truth be told, I don’t think cocoapods is all bad, but I do think it tries to solve problems that doesn’t exist and add new issues in the process.

Some reasons I don’t like cocoapods:
– It’s *very* intrusive.
– It adds a dependency to your project (The irony);
– It adds problems that you wouldn’t have using other solutions;
– You have to wait for cocoapods support when you try new things (Swift, Xcode Beta, etc);
– If you want a different config from the one cocoapods generates, you’re going to have a bad time.
– Way more cumbersome to maintain forks;
– Too much “behind the scenes” configs;
– Very slow compared to git submodules;

But to be fair, there are some positive notes:
– Easier to add an external lib to your project;
– If you don’t like to configure the project your way, it will just do it for you;
– Easier to see what dependencies are outdated;
– Easier to try a lib and discard it;

In my opinion the disadvantages of it succeeds the advantages by a large amount. I never thought “Man, adding a new lib/framework to my iOS project sure is tedious and time-consuming, I wish there was a way to improve it” simply because I think it’s very fast to do it manually and it doesn’t compromise the control you have over *your* project.

This is my justification on writing this post, I just want to show how simple and easy is to use git submodule, a well supported, simple, non intrusive and robust way to add third party libs to your project, without adding any new dependency (Assuming you’re using git).

How does it works?
It’s pretty simple actually, just imagine that the git submodule is nothing more than another git repo inside your own repo. This is particularly good when you work on both projects (main and submodule) because the workflow is basically the same, when you want to work on the submodule project, the way you add,commit,push files is everything you already know and love.

Tutorial
On this tutorial I’ll create a simple Xcode project and add AFNetworking to it. I’ll assume that you already have a git repository up and running with your Xcode project, so I’ll skip these steps and go right to the submodule part.

Cool, you have your project, and you want to add AFNetworking as a submodule, right? Easy, what I like to do is to create a folder on my project structure to host all my submodules, making it easier to find the dependencies. So, let’s create the folder: (Assuming you are in the root level of your project)
mkdir -p Frameworks/External

Now, the *hard* part, adding the submodule:
git submodule add git@github.com:AFNetworking/AFNetworking.git Frameworks/External/AFNetworking

That’s it, the submodule is now added to your project, if you look at your root folder, you’ll see that now you have a new file called “.gitmodules”, if you open it you’ll see something like this:

[submodule "SubmoduleTutorial/Frameworks/External/AFNetworking"]
path = SubmoduleTutorial/Frameworks/External/AFNetworking
url = git@github.com:AFNetworking/AFNetworking.git

This is the config of your submodule, simple, easy to understand what’s going on, no mystery.

Now, the  final step is to just add the files you want from AFNetworking to your project, how you want it, whatever way you think is best, no auto config, no hidden settings.

What I like to do is to just add a group called Frameworks and drag the folder there:

AFNetworking
AFNetworking

That’s it, basically the entire list of steps are:
– git submodule add (repo url) (local path);
– Add files you want to your project;
– Done;

You can see on my github link how the submodule is represented by a link:
(https://github.com/Bunn/Git-Submodule-Tutorial/tree/master/SubmoduleTutorial/Frameworks/External) that goes directly to the host page. Pretty cool, right?

Of course, this is just scraping the surface of what can be done with submodules, but I just wanted to show how simple is to add a submodule to your project.

And later, if you want to clone your repo (or any repo that has a submodule) there’s just one extra step.
git submodule update --init --recursive
This is your “pod install”, but it’s incredible fast compared to the cocoapods alternative (The recursive flag is optional, as you might think, it’s just to get submodules of submodules if that’s the case, but it’s a rare scenario).

This is the link of the repository I used for this tutorial: (Submodule Tutorial)

Conclusion
As I said before, cocoapods is not all bad, but I really think developers should give it a try to git submodule because I’m pretty sure it will solve 90% of problems without adding yet another project dependency. Also, it’s way smarter to decide if it’s better to use cocoapods or submodules once you have at least the bare minimum experience with both approaches so you can weight the options and make the best decision. I’m not a cocoapods hater, as all technologies, cocoapods is just a tool that you need to consider to solve your problems, but I do believe lots of developers think that it’s the only option out there where it’s not true, there’s already a pretty solid solution ready to go with their git repo.
Here’s a link of the oficial documentation ( Documentation )

Also, while we are on the subject, I strongly recommend this read, an awesome post about having to think a bit before adding third-party libs to your apps.
https://sandofsky.com/blog/third-party-libraries.html

Advertisements