Pitfalls of a Legacy iOS Project
How to avoid the unexpected when working on old iOS code
A co-worker and I recently wrapped up a project where we re-skinned an older iOS app with fresh designs. We got to implement new designs from a top-notch design firm, which is the kind of challenge we love. What we didn’t end up loving, though, was working with a legacy codebase that sat dormant for a few years. The state of the app’s code set us back far more than we originally anticipated, causing us to run a bit over the time we originally estimated for the project.
Despite the delay, we completed the project, and learned a few lessons in the process. In this post we’ll share those lessons with you so that you can be aware of a few pitfalls you could encounter the next time you have to update a legacy iOS application.
Don’t Underestimate Legacy Code’s Impact on Application Flow
We had three pieces of information when we started estimating this project: the existing application, a cursory knowledge of its codebase, and the new designs. The new designs and the behavior of the existing application were the driving factor in our estimates for the scope of work, but our merely cursory knowledge of the existing codebase bit us hard when crunch time came.
Unintuitive object responsibility, poor architecture, and copy/pasted code made for an object design that was extremely tightly coupled with the application flow. Many designs changed application flow slightly, and even though changes were slight, we still had to re-factor much of the codebase to accommodate for these.
So, before estimating any sort of re-design – even the most superficial-seeming re-skin – it is recommended you get as familiar with the existing codebase as possible. This will help you estimate new designs more accurately. Then, if for some reason you can’t get dig into the details, you should assume that the legacy code is messy, fragile, and tightly coupled to the UI, and your estimate should adjust accordingly.
APIs Change. Expect Those Changes.
If your app depends on an external platform, and it hasn’t been updated for more than a few months, then I can guarantee those external service APIs have changed. In our case, we had particular trouble with Instagram and the iOS 9.0 release.
Instagram’s API changed the subdomain that their endpoints pointed to, which broke the existing OAuth implementation. This problem caused us to burn more time than expected in authenticating the app with iOS. Additionally, Instagram had deprecated posting content directly to the service via their SDK. This was not documented in the SDK docs, but it was documented in a six month old blog post that we found after hours of creative Googling.
Also complicating our refactor was iOS 9’s extra security around URLs, which broke existing code for integrating with external platforms. We could have saved ourselves time by expecting these changes, and by future-proofing the app for them.
A Small, Clean Storyboard is A Happy Storyboard.
Existing storyboards in the codebase were an annoyance on two fronts: they were slow to open, and they caused headaches when working on features in parallel.
The entire flow of the app was contained in one large storyboard. It was a spaghetti mess of scenes and segues, which made it hard to find scenes quickly. Worst of all, switching from code to a storyboard would often beach ball Xcode for 8-15 seconds, which broke developer flow and the slowdowns aggregated over time.
Then there were the problems caused when two of us were working on different features at the same time, which led to time wasted in merging the storyboard. We found a bug in Interface Builder that would add 0.5 to the position of scenes as soon as it was opened up. This would make a storyboard merge balloon from two or three changes, to 112+ changes. As a result, we had to slowly and painfully coordinate merges on changes we didn’t really care about.
If you’re working on a legacy project, it’s worth the time to break storyboards up by distinct workflows. This will help you avoid the beach ball when you open up your storyboard. You’ll be able to find the scene you’re looking for, and have fewer headaches when merging code.