How to Clean Up the Resources in an iOS Project

Run a Ruby script to clean up unused code

Ashwin Shrestha
Better Programming

--

Photo by pan xiaozhen on Unsplash

Writing code is an iterative process. You write a certain functionality, and after certain months, the requirement may change and you have to remove it. And then another new feature is introduced which can be deemed unnecessary again. But that’s the life of a program: it needs to change as time changes and updates to meet the current requirement. But with the functionalities addition and removal over the time of development, often we end up with unused resources like classes, variables, methods, image assets and localized strings and even dead code. This only increases our computation time and memory. This also makes our code hard to maintain. So it’s always good to clean your code and look for those cases once in a while.

Yes, we have to clean our code, and one year is a lot of time.

But it’s not as hard as it sounds. It’s not that we have to dive deep into every line of code and find those unused files and resources. There are some tools that help us to do that. Today, I am going to list down a few in this article that I use for this. If you use any other tools, do let me know in the comment section below, so I could also go and try out those.

First, let’s list the resources/files that we are going to talk about in this article.

  1. Unused swift functions and variables.
  2. Unused localized strings.
  3. Unused image resources.
  4. Visualizing dependency graphs in the project.

So let’s get started.

Unused Swift Functions and Variables

For this I use a Ruby script, which you can find here. This script searches for unused swift functions, and variables at the specified path.

Go to the link and clone the repository or download the unused.rb file, and place it in the root directory of your project.

For demo purposes, I have made this sample app Colors and added a method setUpCameraView() in ViewController.swift which has not been called from anywhere.

import UIKitclass ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
}
func setUpCameraView() { }}

Now open the terminal, navigate to the project directory, and enter the command.

ruby unused.rb

The output of the above is:

Total items to be checked 6
Total unique items to be checked 6
Starting searching globally it can take a while
Item< func setUpCameraView [] from: Colors/ViewController.swift:22:0>
Item< class AppDelegate [] from: Colors/AppDelegate.swift:12:0>
Item< var window [] from: Colors/AppDelegate.swift:14:0>

So, we see that setUpCameraView() is not called from anywhere in the app and is safe to remove.

Note: Had the method been a private method, it would not have shown in the result list. We should be careful about this, though.

If you want unused private methods also to be shown in the result, we need to update the unused.rb file. Just add private func in the list of line matches on line 11 of the file.

if match = line.match(/(func|let|var|class|enum|struct|protocol|private func)\s+(\w+)/)

In this way, we can list down all the unused functions, constants, variables, class, enum, struct, protocols in the project which has not been used anywhere.

You can integrate it to the Xcode as well with a Custom Build Phase/Run Script, the details are explained in the repo itself.

Unused Localized String

Another occurrence of unused things in the codebase after iterations are localized strings. We often end up with them, although they are not used anywhere in the project. To remove these, I use abandoned-strings by ijoshsmith. This program will find the unused localized strings from all *.strings file in a given path.

The thing with this command-line program is that it’s still in swift 3, but blanksblanks, has migrated it to swift 5 here.

Steps to use this command-line program is as follows:

  1. Clone the project first and then run it.
  2. An executable is generated in Products folder, navigate to the folder where the executable is generated by clicking “Show in Finder.

3. Now open the terminal with this executable’s file path as terminal’s base path:

Ashwins-MacBook-Pro:~ ashwin$ cd /Users/ashwin/Library/Developer/Xcode/DerivedData/AbandonedStrings-gnlgdvyltxanfeeyscyegpweluex/Build/Products/DebugAshwins-MacBook-Pro:Debug ashwin$

4. After this, enter the command below to list all the unused localized strings in your project.

Ashwins-MacBook-Pro:Debug ashwin$ ./AbandonedStrings /Users/ashwin/Desktop/Personal/Colors/Colors

For demo purposes, I have added two localized strings, but I have not used it anywhere.

"ViewController_title" = "Hello";
"ViewController_subtitle" = "Adios Amigo";

Which gives us the result:

Ashwins-MacBook-Pro:Debug ashwin$ ./AbandonedStrings /Users/ashwin/Desktop/Personal/Colors/Colors
Searching for abandoned resource strings…
Abandoned resource strings were detected:
/Users/ashwin/Desktop/Personal/Colors/Colors/Localizable.strings
ViewController_subtitle
ViewController_title
Ashwins-MacBook-Pro:Debug ashwin$

So, in this way, we can list all the localized strings not used in the project and remove those.

Note: Make sure the subpath for analyzing is your project’s folder and it doesn’t include the Pods folder, because then it will try to find the unused localized strings in Pods as well, which we do not want.

Unused Image Resources

To list/remove unused image assets in my project, I use this powerful command line util called FengNiao. All you need to do is:

> git clone https://github.com/onevcat/FengNiao.git
> cd FengNiao
> ./install.sh

Note: You need Swift Package Manager (as well as Swift compiler) installed in your macOS.

Now, just navigate to your project folder and then enter the command:

Ashwins-MacBook-Pro:Colors ashwin$ fengniao

The output for my sample app that we have been using in this whole article, as we have not added images yet:

Searching unused file. This may take a while...😎 Hu, you have no unused resources in path: /Users/ashwin/Desktop/Personal/Colors.

Now let’s add an image in Assets.xcassets and then hit the command again (but we are not using the image anywhere):

Searching unused file. This may take a while...
1 unused files are found. Total Size: 316.22 KB
What do you want to do with them? (l)ist|(d)elete|(i)gnore

You can → delete, list or ignore it.

When I wished to delete the result, the response I got:

What do you want to do with them? (l)ist|(d)elete|(i)gnore d
Deleting unused files...⚙
1 unused files are deleted.
Now Deleting unused Reference in project.pbxproj...⚙
Unused Reference deleted successfully.

Or you can list them as well:

What do you want to do with them? (l)ist|(d)elete|(i)gnore l
316.22 KB /Users/ashwin/Desktop/Personal/Colors/Colors/Assets.xcassets/sampleImage.imageset
1 unused files are found. Total Size: 316.22 KB

There are several options for the command, I encourage you to go and look at those in the repo’s README.md. However, I would like to point out that, we can exclude the assets search in Pods and Carthage.

I have added Visualizing Dependency Graph in the project in the list, but I think the article is already long enough to explain Dependency Graph Visualization in the same article. To learn about Dependency Graph Visualization, check out this post.

And if you have any questions or suggestions, feel free to post them in the comment section.

Also, if there are other libraries or Utils you use, please feel free to share them in the comment section below.

Thanks for reading.

Happy coding 🙂

--

--