Unused images and resources clean up in Xcode

Unused images can exist as a result of iterations in a project. Once a feature is no longer needed and remove, it’s not always cleaned up completely. Therefore, it’s useful to know how to clean up your Xcode assets.

Just like in my blog post on cleaning up unused localized strings, I’ll go over a few tools which you can use to clean up your project:

Unfortunately, a lot of tools like Slender used to do the job but are no longer maintained. Therefore, let’s see what is working nowadays!

For this, I’m going to use my day to day job project Collect by WeTransfer in which the assets have not been cleaned in 2 years.

Cleaning up unused images using FengNiao

FengNiao is a command-line tool mostly written in Swift. It’s open-source and available on Github. It can be installed by cloning the repository and running the install script:

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

Using it is as simple as changing directory to your project folder in the terminal and executing FengNiao:

> fengniao

It will show you the results at first after which you have the option to delete, ignore or list the unused resources.

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

Listing the files showed that the dependencies were also checked. Obviously, we don’t want to focus on those as they’re not managed by us.

1.57 KB /Users/antoinevanderlee/Documents/GIT-Projects/WeTransfer/Coyote/Submodules/Rabbit/Submodules/Alamofire/docs/docsets/Alamofire.docset/Contents/Resources/Documents/img/gh.png

Apart from listing dependency assets, the tool is also listing images for documentation folders. Therefore, we need to run the tool again with a few extra options.

We can list all available options by using the –help parameter.

$ fengniao --help
Usage: fengniao [options]
  -p, --project:
      Root path of your Xcode project. Default is current folder.
  --force:
      Delete the found unused files without asking.
  -e, --exclude:
      Exclude paths from search.
  -r, --resource-extensions:
      Resource file extensions need to be searched. Default is 'imageset jpg png gif'
  -f, --file-extensions:
      In which types of files we should search for resource usage. Default is 'm mm swift xib storyboard plist'
  --skip-proj-reference:
      Skip the Project file (.pbxproj) reference cleaning. By skipping it, the project file will be left untouched. You may want to skip ths step if you are trying to build multiple projects with dependency and keep .pbxproj unchanged while compiling.
  --version:
      Print version.
  -h, --help:
      Print this help message.

The exclude option is the one we need. After looking into all the paths listed for Collect it turned out that we could ignore quite a few paths. It results in the following command:

fengniao --exclude Carthage Pods Submodules Vendor guides fastlane

This tells the tool to ignore the folders which contain the dependencies, as well as our documentation and Fastlane folder. The final result contains 44 unused resources to clean up:

Unused images clean up using Fengniao
Unused images clean up using Fengniao

To verify that these are indeed unused assets I’ve randomly picked a few and did a search in Xcode. It turned out that those assets are indeed unused and could be cleaned up.

Running the tool again proved that it’s working as expected!

$ fengniao --exclude Carthage Pods Submodules Vendor guides fastlane
Searching unused file. This may take a while...
😎 Hu, you have no unused resources in path: /Users/antoinevanderlee/Documents/GIT-Projects/WeTransfer/Coyote.

Unused images clean up using LSUnusedResources

LSUnusedResources is a Mac app which does exactly the same as FengNiao: cleaning up unused images and resources. It’s open-source as well but no longer maintained. At the moment of writing, the last commit already dates back to a year ago. However, it still runs and is therefore worth a try!

The executable can be downloaded from the Github page. It may tell you that it’s unsafe to open. If so, you can use control + open and use it. After running it with the default settings, it shows almost the same results as FengNiao:

Unused images result with LSUnusedResources
Unused images result with LSUnusedResources

Just like we did with FengNiao we should now run it again with the excluded folders. We have to fill in the Resource Suffix by separating the folders with a pipe symbol:

Carthage|Pods|Submodules|Vendor|guides|fastlane

The result is as following:

Total: 106, unused: 21, time: 1.53s, size: 328.92

Those are all unused assets and can be easily removed using the delete button in the application.

Comparing the results: FengNiao or LSUnusedResources?

Comparing the two outcomes shows quite some differences:

FengNiao:          44 unused files / Total Size: 440.06 KB
LSUnusedResources: 21 unused files / Total Size: 328.92 KB

At first, this seems to be mainly related to the two extension targets which we have in Coyote. FengNiao is correctly checking those where LSUnusedResources seems to ignore them.

To be entirely sure I’ve created a branch for each tool and compared the changes. This confirmed that FengNiao did a better job and found more unused resources.

Is it always safe to clean up those unused images?

Definitely not! It’s recommended to go over the assets before you delete them. There is a common example of assets which are used but still listed as unused. This is when you build up a reference to a resource based on certain conditions.

For example, in Coyote we’re using the following code:

UIImage(named: "\(iconName)\(iconSize.sizeString)")

It turned out that all those images were listed in both results and it’s therefore required to go over the results manually before deleting.

Bonus: Clean up your Xcode developer files

As you’re already into cleaning up, how about cleaning up your Xcode developer files as well?

There’s a great tool called DevCleaner which will easily delete up to 20GB of unused data for you. This is how it looked for me after running it for the first time:

Cleaning up your Xcode developer files using DevCleaner
Cleaning up your Xcode developer files using DevCleaner

Do know that this app will delete all your old iOS versions by default. In my case, for example, it selected all iOS 11 and 12 device support files leaving me with device support for only iOS 13. This is obviously not what you want. Therefore, go through the selection and adjust to your needs.

Conclusion

Cleaning up your project to delete unused images is definitely worth a try. It will keep your project clean from assets you’re no longer using. Keep an eye sharp and go over the results manually before deleting them.

Thanks!