Modernise an established Objective-C module inside a live healthcare app without disrupting production behaviour.
Doctor Care AnywhereLegacy Modernisation Inside a Live Healthcare App
Rebuilt an Objective-C module in Swift inside a production MVVM-C healthcare application, without changing what patients experienced.
Understand the legacy module first, rebuild it in Swift behind stable interfaces, and protect the change with 80%+ unit-test coverage.
Senior iOS Developer: migration, security hardening, SonarQube quality fixes and production monitoring.
The module moved from Objective-C toward Swift with no risky full-application rewrite and behaviour preserved.
- Role
- Senior iOS Developer
- Platform
- iOS
- Languages
- Objective-C, Swift
- Architecture
- MVVM-C
- Quality
- XCTest, SonarQube
- Dependencies
- CocoaPods
- Monitoring
- RayGun
- Analytics
- Amplitude
- Payments
- Stripe
- Delivery
- Azure DevOps
Project Context
Doctor Care Anywhere is a digital healthcare platform providing patients with access to healthcare services through mobile technology.
I joined an established iOS codebase containing a mixture of legacy Objective-C and newer Swift development. One of the key reasons I was brought into the project was my experience working with both languages.
The team needed to modernise an existing area of the application by understanding its Objective-C implementation and rebuilding that functionality in Swift, without disrupting the behaviour of the production application.
What patients see
The Engineering Problem
The task wasn't simply Objective-C → Swift.
Before replacing it, I needed to understand:
- ▸how the existing Objective-C implementation worked;
- ▸which components depended on it;
- ▸how data travelled through the module;
- ▸which behaviours had to remain unchanged;
- ▸how the new Swift implementation would interact with remaining Objective-C code;
- ▸what regression risks the migration introduced;
- ▸how the implementation fitted into the existing MVVM-C architecture.
→The challenge was therefore to modernise the implementation while maintaining compatibility with the existing application.
Legacy Modernisation
Where the legacy module sat
Rebuild, not a syntax conversion
Instead of treating the work as a direct conversion, I first analysed the responsibility of the legacy module and its relationships with the wider application. The new implementation was then rebuilt in Swift while preserving its required interfaces with the remaining Objective-C codebase.
- 1−Objective-C implementation
- 2−Behaviour not obvious from the UI
- 3−Dependencies known only by reading the code
- 4−No safety net for change
- 1+Swift implementation
- 2+Same externally observable behaviour
- 3+Stable interfaces to remaining Objective-C code
- 4+Unit tests protecting the migration
What had to stay true
The application could not be rewritten completely at once. The new Swift implementation needed to coexist safely with existing Objective-C components.
Existing functionality had to remain consistent while the underlying implementation changed.
Understanding which components depended on the legacy module was important before replacing it.
Changes to an established healthcare application required careful verification, because an apparently isolated change could affect other flows.
Testing Strategy
Unit testing was an important part of the migration. The project targeted at least 80% unit-test coverage for the work I was responsible for.
Testing was particularly valuable during the Objective-C → Swift migration because it provided a safety mechanism while changing the implementation underneath existing behaviour.
Does the Swift implementation produce the same expected result?
What happens when unexpected or incomplete data is received?
Does the module behave correctly when dependencies fail?
Can future development modify the module without silently breaking existing behaviour?
→This made testing part of the migration strategy rather than something added after development.
Technical Challenges
The first difficulty was understanding an existing implementation rather than building a greenfield feature. Legacy code often contains important behaviours that are not obvious from the UI or requirements. Replacing the module therefore required understanding what the existing code was actually doing before deciding how the new implementation should work.
The migrated module still lived inside an application containing Objective-C. The migration boundary had to be carefully managed so Swift and Objective-C components could continue communicating without forcing an application-wide rewrite.
Improve the implementation while keeping the behaviour stable. Changing too little simply recreates the legacy design in another language; changing too much increases regression risk. The solution was to modernise the implementation while keeping externally observable behaviour and interfaces stable where necessary.
Refactoring legacy functionality while maintaining a high unit-test coverage target required structuring the Swift implementation so important behaviour could be tested independently. This encouraged clearer responsibilities and reduced coupling between components.
The module couldn't be designed as an isolated application. It needed to follow the existing MVVM-C architecture, dependency conventions, navigation model, monitoring tools and engineering workflow already used by the wider iOS application.
Healthcare software raises additional engineering concerns around application security and sensitive information. Security-related work had to be considered alongside feature development, architecture and maintainability rather than treated as a separate afterthought.
Technology Map
My Contribution
- ▸Understanding an established Objective-C implementation
- ▸Rebuilding module functionality in Swift
- ▸Maintaining compatibility with the wider Objective-C/Swift application
- ▸Working within the MVVM-C architecture
- ▸Contributing to application security improvements
- ▸Resolving SonarQube code-quality findings
- ▸Writing unit tests targeting at least 80% coverage
- ▸Working with CocoaPods-managed dependencies
- ▸Supporting production monitoring through RayGun
- ▸Working with Amplitude analytics
- ▸Working with Stripe payment functionality
- ▸Using Azure DevOps as part of the engineering workflow
Outcome
The work helped modernise an area of an established iOS application from Objective-C toward Swift without requiring a risky full-application rewrite.
More importantly, the project demonstrates experience working with a real production system containing legacy code, architectural constraints, security requirements, third-party integrations, automated quality controls and production monitoring. That is very different from building a clean sample application from scratch.
Some application versions, implementation details and internal architecture are not publicly available. This case study focuses on my engineering responsibilities, technical decisions and problem-solving process while intentionally excluding proprietary source code and sensitive security information.