We massively improved the app‘s performance and stability over 18 months, which was positively matched by massive improvements in the app store ratings.
23 MyVodafone developers
The MyVodafone apps are used by 800,000 people a month to manage their Vodafone services, check their balances, and pay their account.
The app was a patchwork of different designs and behaviours, with a slow and unreliable user experience, sitting on top of 5 years of technical debt.
The app has a surprising number of features, it has 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.
Whilst there were 7 to 8 front end web developers, there was only 2 Android developers, and 2 iOS developers (including me).
There was a lot of work done to improve the app that was interwoven with new features and alignment with multiple marketing campaigns. I’ve documented the most pivotal and interesting changes.
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.
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 soley 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 enabled them to raise sprint tickets directly from the crash logs.
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 gone, and dozens of crashing events dissapeared 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 across both the mobile apps and the website from 20 seconds to 4.
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.
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.
Because our application was built before iOS multi-tasking existed, it did not handle re-authentication and so it 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.
During the app data load, it makes an API call to get a list of services, then it makes a details API call to each item in the list sequentially. For customers with multiple services this resulted in the app being un-usable for up to 20 seconds.
We modified the existing data fetching code to be multi-threaded using iOS GCD, reducing load times for most customers from 12 to 25 seconds to only 4 to 5 seconds.
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.
Worked with consultants from Thought Works to add data caching into the app, and updating 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.
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 error 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, get what you want, and get out as fast as possible.