How to remove unused code in Swift
When a code migration or a refactor or a feature development comes to the end the question is always the same: “am I sure I did a clean job and I removed everything that is no longer needed?”
No, despite the PR review you can’t be 100% sure.
It’s probably useless to underline how important is to have a clean codebase, sharing architecture and programming style; so it becomes necessary to do this kind of code gardening.
Manually however it’s very complex and prone to oversights; for this reason I’ve searched for an automated solutions and among all, the one I liked more is called Periphery.
Periphery
It’s an open-source tool well documented in the Github repo which allows you to identify at build time all code not used inside the project.
👨🏫 In a nutshell, how does this work?
🙋♂️ After your project is built, Periphery performs an indexing phase. Once indexing is complete, Periphery analyses the references graph to identify unused code. Then walks the graph from its roots to identify declarations that are no longer referenced.
Periphery is able to find unusedclass
, struct
, protocol
, function
, property
, constructor
, enum
, typealias
, associatedtype
.
You can either run it in Terminal or integrate it in Xcode. For personal taste I preferred the Xcode solution.
The integration steps are very easy; you have to create a new dedicated target, and among its build phases add the command that launches Periphery: periphery scan
.
Then when you’ll run the project Periphery will start scanning the app reporting as many warnings as unused code found.
How to configure Periphery
To work properly it needs some information about the project like:
- Project name
- Scheme
- Target
- Paths to exclude (if needed)
- Xcode related configurations and verbosity
Here there is an example of a command:periphery scan --project PROJNAME.xcodeproj --schemes TESTSCHEME --targets TARGET --report-exclude PATH/TO/FILE/TO/IGNORE/* --clean-build --format Xcode
💡 Very handy but less famous, is the possibility to add to the project a configuration file .periphery.yml
to parameterize all the available information and to setup the scan.
Once you’ve adjusted it to your preferences and added this file to the project, from the build phase, you would be able to only run periphery scan
and you’re done!
Conclusion
Here you can see some numbers: this is the output of using Periphery on a project that I thought wasn’t so bad in terms of unused code.
Periphery has fully responded to my needs and in my mind it has opened up a world of possible evolutions. In fact, it would be interesting to explore the automation of these checks directly in the pull request creation phase, to provide to the developer a first automatic review with great impact.
🇮🇹 Italian version here.