Improving MyVodafone App Experience
18 months of incremental improvements to performance and stability of the MyVodafone mobile apps created dramatic improvements to CSAT and App Store ratings, whilst never alienating customers.
3 iOS developers
23 MyVodafone developers
01 // Overview
The MyVodafone web and mobile apps are used by 800,000 people a month to manage their Vodafone services, check their balances, and pay their account.
The mobile apps were a patchwork of different designs and behaviours, with a slow and unreliable user experience, sitting on top of 5 years of technical debt.
The MyVodafone app has a surprising number of features - over 85 screens of functionality.
Changes to the app need to be made thoughtfully. It’s used by a wide range of customers with very different use cases and sets of needs, ranging from individuals on prepay and monthly accounts to enterprise scale organisations.
Whilst there were 8 front end web developers, there were only 2 Android and 2 iOS developers (including myself) supporting the mobile apps.
02 // Process
There was a lot of work done to improve the app that was interwoven with new features and alignment with multiple marketing campaigns. These are the most pivotal and interesting changes.
Initial triage work
The first code changes I made were to address the obvious problems - reducing Xcode compiler warnings and static analyser warnings from 800+ to zero.
This cleared two dozen long known bugs in the app.
To ensure this didn’t happen again, I added a build task to the project that would fail and abort the build process if there were any compiler or static analyser warnings.
Crash logging & analysis
There was no crash logging in either the iOS or Android apps - we were blind to our app stability for our customers.
I installed Crashlytics and after it went into production we quickly discovered a significant number of problems we were previously unaware of. The subsequent release consisted solely of patches for the top 25 bugs on each platform.
To ensure we stayed on top of this we gave the User Acceptance Testing team access to the Crashlytics dashboards, and empowered them to raise sprint tickets directly from the crash logs.
Added package managers
Neither the Android project or the iOS project used package managers. They simply copied libraries they used into the app project.
On Android we correctly setup Gradle to handle package management, on iOS we converted the project to CocoaPods. We then upgraded all our dependencies to the latest versions and refactored the supporting code as required.
The result of this work was another two dozen long known bugs in the app were eliminated, and dozens of crashing events disappeared from the Crashlytics dashboards.
In a conference call I overhead our Oracle database lead mention 4 hits on the user entitlements query every time the mobile app authenticates.
Given this was an expensive and slow query I started investigating. Working with a senior backend systems developer we traced the issue to our 4 production caching servers. Due to a misconfiguration they were all individually making the call to entitlements instead of caching a single call.
Once the code had been fixed to correctly propagate the entitlements call, the caching and reduced Oracle workload improved login times from 20 seconds to 4 seconds across both the mobile apps and the website.
To suport an exact animation requirement from a previous design team, the iOS app was built on a completely custom navigation system. Unfortunately this was now causing memory issues, poor performance, and completely stopped VoiceOver from working.
I refactored the entire app to remove the custom navigation system and use the iOS standard instead. This resulted in a better user experience and app stability, but most importantly enabled VoiceOver for accessibility.
Menus & sign-in screens
Due to changes in iOS 7, the layouts in our navigation menus and our sign-up screens were now a visually a jumbled mess.
I fixed all the sign-up screens layouts, I fixed the menu layout and updated it to follow the branded designs already in the Android app. These simple changes resulted in a double digit percentage increase in both customer sign-ups and customers using features from the menu.
Multi-tasking & re-authentication
Because our application was built before iOS multi-tasking existed, it did not handle re-authentication. The quick fix (that became permanent) was to make the app quit when the user went to another app or the home screen.
I added multi-tasking to the app, but more importantly added an authentication manager service that handled automatic re-authentication. The result is customers can jump in and out of the app at will. This resulted in a huge increase in app ratings and decrease in aborted account payments.
Multi-threaded data fetching
During the app startup an API call is made to get a list of services for an account. Subsequent API calls are made to retrieve the details for each service.
For customers with multiple services this resulted in the app being effectively frozen and un-usable for up to 25 seconds every time it opened or refreshed data.
We modified the existing data fetching code to be multi-threaded using iOS GCD (Grand Central Dispatch), which reduced load times for most customers from 12 to 25 seconds to only 4 to 5 seconds.
Always On experience
One of the biggest problems still remaining in the app was when users went out of coverage, or one of our core services was temporarily unavailable. The user experience was effectively reduced to a “try again later” message.
Working with consultants from Thought Works we added data caching into the app, and updated the UI to clearly explain when data was cached or live. The result was customers being able to see their services and balances when offline or during outages.
03 // Learnings
Over this two year period, I learned a lot of valuable non-technical lessons:
Visibility of problems is important. When our project had hundreds of compiler warnings, no one paid attention to adding a few more. When our project had zero compiler warnings, even a single issue was fixed immediately.
Always be curious. If I hadn’t heard the database lead mention 4 hits on his service and then followed my curiousity, we’d still have 20 second login times.
We made a lot of changes to the app, comparing it from when I started to when I left is a startling difference. However our customers never noticed - because we implemented this big change as many small changes over time.
Peformance and reliability are important to customers. We were able to make a direct correlation between the changes we made and the app reviews. The culmination of these changes raised the app rating from 1.3 stars to 4.2 stars.
Apps are at the mercy of their data sources. If a data source is unreliable, the customer perceives the app as being unreliable. This problem is not insurmountable.
There are different kinds of apps. Some are destinations, and some are tools. Don’t try to force a tool to be a destination. A tool should allow you to get in, do what you want, and get out as fast as possible.