🏈 Rugby: Optimise CocoaPods project
Tags: xcode, indexing, swift, cocoapods
Published: 2021-06-08 15:39:17

Do you have problems while working on a huge project with a large number of pods in **Xcode**? Maybe endless indexing? **Xcode** is always freezing during navigation through a project or while editing it? Slow rebuilding pods targets which have been already built recently?
<br>

## 🦖 Prequel

In recent years I have been often annoyed while working on huge projects with [CocoaPods](https://github.com/CocoaPods/CocoaPods). And the final straw was the new project last summer 2020.

First of all, I decided to measure how much time I spend on building projects during my workday. So my first **macOS** project was born - [Buildyosh](https://github.com/swiftyfinch/Buildyosh).

As result, I realized that I spend about two hours a day fighting **Xcode**. Add a minimum of two hours for all sorts of communications and you get a four-hour workday at best.

Finally, I tried to get better hardware at the expense of the company, but I would have to wait for nearly nine months. There must be another way.
<br>

## 🐞 The problem

Before doing some optimization the one needs to figure the problem's nature:

- Slow and unnecessary indexing of remote pods targets, which implementation I rarely try to edit;
- Redundant rebuild time, probably as a result of problems, related to [CocoaPods](https://github.com/CocoaPods/CocoaPods) or **Xcode** build system;
- Freezing UI during navigation through a project or editing it;
- Broken or extremely slow autocompletion;
- Noisy laptop turbines, heated aluminum, and infinite spinning pinwheel.

&nbsp;

## 🏰 Solution #1 - Separate Xcode project

I moved my feature part to a separate dependency and made my own small **Xcode** project. And it solves a lot. But the time for integration is coming. And you have to open an enormous main project again and suffer.

This solution saves plenty of time but still isn't good enough. Sometimes integration takes most of the time. But anyway, that's something.
<br>


## 🛠 Solution #2 - Disable Xcode indexing for good

Yeah, I can turn off indexing and lose the ability to use some features. And it solves the majority of problems too.

<pre><code class="terminal"><div class="line"><span class="red-circle">•</span><span class="yellow-circle">•</span><span class="green-circle">•</span> defaults write com.apple.dt.XCode IDEIndexDisable 1</div></code></pre>

But I will have to forget about navigating just by clicking on the class. Instead, I will have to use search frequently. Then I need to copy, paste, and so on.

I have been using that solution all the time until I found the better one.
<br>

## 🖥 Solution #3 - Hardware

I could buy a new **MacBook Pro** or request it from the company. It's the easiest solution if it's available. But I think time will pass, the project will grow, and the hardware will become old and slow again.

I couldn't get a new **MacBook** from the company in short time. And also, I didn't want to buy it for myself.

But in February 2021, I finally bought my own **Macbook Air M1**. It is a tremendous boost to my productivity. It's a pity, I didn't have it in summer 2020.
<br>

## 🏈 Solution #4 - Rugby

After a while, I realized how to solve the problem at the software level. I don't need all of the targets in a project, only some of them. Perhaps ten percent or something about that.

First of all, I was trying to manage this manually. But it was a hard routine action. And I decided to experiments with **Ruby** scripts. I wrote a bunch of scripts and they worked sometimes. In some cases, I did this part manually.

The main idea was to build all secondary targets and remove them from the **Pods** project. I had plenty of decisions, which weren't well-suited, and I'm noobie in **Ruby** programming. I think on trying to write complex utility with limited language knowledge is not a good idea. Maybe one average file is fine, but not a bunch of them.

> Also, I tried [CocoaPods Binary](https://github.com/leavez/cocoapods-binary) and similar solutions. But I couldn't run them on the first try and the last update was a year ago. Also, the main problem was that they change **Podfile** and **Podfile.lock** respectively. It did not suit me, since dozens of other people are working on the project and everyone has their own tasks. 

At this moment, I have already had some experience and have been ready to rewrite all from scratch using **Swift**. It's my primary language and there are enough useful **SPM** packages for command line utility development.

When I had the first utility version, I organized an alpha test. Mostly, I was testing on my own. At the end, my secret colleague joined me.

Then there was a beta test for **~30** users, based on statistics on **GitHub**. I fixed some critical bugs and added new features by useful feedback. It was an important step.

And finally, I released a stable [Rugby](https://github.com/swiftyfinch/Rugby/releases/tag/1.0.0) version with new beta command.
<br>

## 🏁 Conclusion

As a result, I almost managed with extensive productivity problems and made a profitable home project. Feel free to use it for your needs. Maybe you have some common problems. You can find all the additional information on [Github](https://github.com/swiftyfinch/Rugby).

It's another story about solving one of my daily problems.\
I'm not sure, maybe it's not the last one about **Rugby**.

**P.S.** While I was trying to write the utility using **Ruby**, I loved that language even more. Also, I was watching **Ted Lasso** series during this development. So, the name **Rugby** is just a word-play. Like **Ruby**, but with **g**. It's pronounced as **[ˈruːgbɪ]**.