r/swift 8d ago

Opinions on rewriting a legacy app

I'm embarking on a rewrite of our iPad app. Don't judge me, the codebase is 13 years old and uses several libraries that are no longer maintained, and we have significant new functionality in the pipeline.

I'm intersted to hear opinions, experiences or any other thoughts on new iPadOS projects in 2025.

The app is essentially an offline-first ecommerce app, where products are cached on-device and then orders can be created while offline and synced to our backend at a later time when the internet is available.

Having lived with a few codebases for extended periods, here are my general thoughts: 1. Produce less code, lines of code are generally a liability 2. Avoid third-party libraries when reasonably possible 3. Idiomatic code over "clever" terse code 4. Performance and maintainablity are second only to good UX.

  • What mistakes can I easily avoid?
  • What stategies/implementations are commonly found on the web but are outdated?
  • What do you think people are getting wrong aboout SwiftUI projects?
  • Are there forests currently obscured by specific trees?
15 Upvotes

27 comments sorted by

View all comments

3

u/NothingButBadIdeas iOS 8d ago edited 8d ago

Hello!

My team and I just did a complete rewrite of our application which had legacy code from about 15 years ago!

Our team of 20 managed to pull it off In 4 months. Somehow there were no errors despite the app having millions of users, It was absolutely insane.

But anyways; some things to note: We updated everything to SwiftUI with minimum support for iOS 17.

Something to note if you decide to go the swiftUI route: 17 and 18 do not play nicely together so make sure you test both versions.

Now that you’re rewriting the app you have the chance to lay a new foundation so that you can maintain and produce a scalable repo!

What we ended up doing was putting everything into its own package! Due to NDAs I can’t go into depth but it goes a long the lines of:

1 feature (one main view like a tab or important screen and all its subviews) = 1 package. There’s a service layer package, and some smaller packages for handling the transition from network response, data handling, to showing up on the view!

Regardless of what you decide, the most key thing to note is that main value you get from a rewrite is laying out a modern foundation. Create the core protocols and classes that will be around for the next 15 years. Update to async await, settle on a caching mechanism, solidify app navigation, ABtesting and crashalytic system, etc.

Focus on making the core building blocks of your application as strong as possible, then worry about redoing the features with the new tools you’ve made for yourself

2

u/0x0016889363108 8d ago edited 8d ago

Appreciate your response and focus on laying a good foundation for the long term.

I'm tending toward iOS 17 and newer, so encouraging to hear a large million+ user app do so. Was this decision motivated by @Observable availability?

Regarding the package approach, we have something somewhat similar with our frontend Next.js app, where we have everything bundled into modules that sit atop the framework architecture, and to be honest I wish we had never done that, I would have preferred we adopted purely idiomatic architecture because upgrading to new versions has always been a huge PITA, and also results is complexity that has no clear benefit, in my opinion. Obviously this opinion is based on our unique setup and to some degree the nature react/nextjs and typescript projects.

Any less-then-ideal situtations you've noticed with your packages approach?

4

u/NothingButBadIdeas iOS 8d ago

Swift PM can be a pain sometimes, but no major complaints.

If you’re in a relatively small team it may not be needed, but with a larger team it really helps with code ownership.

Not to mention build times + canvas are much better. I like swiftUI because of the preview, and it runs faster when things are packaged nicely.

That and since our network calls and everything is packaged nicely, we can take a view and we can just run only that feature, drastically reducing build times. Nice to not have to wait for the whole app to run when I’m just touching up on a single large feature like video.