Revamping Your iOS App: Choosing Between Refactoring and Rewriting.

Rob Maltese
oneleif
Published in
4 min readJan 3, 2024

Two years ago, I plunged into iOS development with no prior experience, channeling my efforts into creating HeatBuddy — an app helping users find affordable home heating oil. Achieving the milestone of version 1 on the App Store after eight months was immensely rewarding.

As aspirations for new features and bug fixes emerged, a pivotal question surfaced: refactor or rewrite the entire application? Confident in my ability to create a cleaner and more reusable codebase, I chose the latter against widespread advice. Little did I know, that this decision would lead me into the complexities of scope creep and the uncharted realm of server-sided Swift.

Despite the advice of numerous individuals, I confidently opted to initiate a ground-up rewrite of the entire application. Additionally, I ventured into the realm of back-end development using Vapor, a server-side Swift framework. Although I was convinced this was the optimal approach, reality proved otherwise.

Feature Whirlwind: The Surprising Adventures of Scope Creep!

Navigating the intricate landscape of refactoring or rewriting projects, I’ve encountered firsthand the challenge of scope creep. Completing a task seems like the final stretch, only to find another compelling addition lingering on the horizon before the production push. It’s never a mere feature addition; in my case, a seemingly innocent enhancement spiraled into a cascade of requirements. The introduction of a new feature necessitated the incorporation of fresh routes into the back end, triggering the need for additional middleware for authentication. This, in turn, led to the integration of token authentication and the implementation of password resets with reset tokens.

The interconnected nature of these developments creates a domino effect, unveiling more complexities tied to a seemingly straightforward feature. Adding to the complexity, my foray into server-sided Swift for back-end development was uncharted territory, amplifying the challenges associated with this unexpected journey.

Striking the Balance: When Refactoring Falls Short and a Rewrite is Tempting

Engaging in life involves weighing the pros and cons, and the same holds true for the decision to rewrite an application. The benefits of rewriting are evident — it elevates code quality, enhances performance, and eradicates technical debt. The process opens avenues for innovation, providing developers with a chance to employ newly acquired techniques and integrate high-quality tests into the fresh codebase.

However, the flip side is marked by challenges. The extensive time required for rewriting poses a significant drawback, and the associated expenses can soar, especially if external talent is enlisted. The risk of introducing new bugs and technical debt not present in the previous version adds a layer of complexity. Moreover, substantial alterations to design or user experience might evoke resistance from users, potentially diminishing the appreciation for the time and effort invested in the rewriting endeavor.

Refactoring: Advantages and Considerations

Refactoring presents a set of clear advantages and considerations. On the positive side, it proves to be a less time-consuming endeavor and minimizes the risk of introducing new bugs and technical debt. The incremental nature of refactoring allows for ongoing changes and improvements, fostering valuable feedback from the user base. This iterative process not only aids in gauging user reactions but also steers the development in a favorable direction for continuous enhancement.

However, it’s essential to acknowledge the limitations of refactoring. While it significantly reduces technical debt, it may not entirely eliminate it. Additionally, refactoring might not offer the opportunity to address deep-seated architectural issues. Drawing from personal experience, I grappled with issues related to state management and data passing. Despite these challenges, refactoring fell short of rectifying these specific concerns, such as reinitializing view models instead of reusing instances. In such cases, a comprehensive rewrite seemed more appropriate, highlighting the nuanced considerations involved in choosing the refactoring path.

Taking Baby Steps: Progress in Every Stride

If you were to ask me for advice, I’d throw out the age-old wisdom — it depends. How colossal is your project? Are you flying solo or do you have a team by your side? And if you’re part of a team, have you all huddled up to chat about the pros and cons?

Reflecting on my own project, I’d cast my vote for the refactoring route. I’d kick things off with a dash of UI design magic while keeping the trusty existing backend in play. Tinkering with a few features and implementing the changes I desired would be the game plan. This way, I could leisurely craft the new backend, one brick at a time.

These petite, incremental changes would have let me spruce up the application while getting the hang of the art of refactoring. It’s like taking a scenic route — a bit slower, but oh, the sights you’ll see! This approach is especially handy for team players or those donning the contractor hat, offering a chance to level up skills while fine-tuning the digital masterpiece.

If you want to stay more up to date on my development, or connect with me on social medias. Feel free to follow me out over at Twitter.

--

--