Maintaining Mobile Apps is Hard
In the world of software-as-a-service, you, the developer, always have access to your production code. Need to push a bugfix into production? No problem. Need to update a variable? No problem. Just change the code, commit, press a few buttons and you’re done. I’m assuming, of course, you’ve adopted processes for continuous integration and continuous delivery and deployment.
Oh, you need to update a mobile app? Not so fast …
Once you’ve updated your app, now you send it to the App store and wait, and wait, and wait. A few days later, assuming it wasn’t rejected, it’s available for users to download at their will. So now you wait again a few days for users to download the update.
In the meantime, you’re getting one-star reviews in the app store and users are deleting your app from their devices, all the while you’ve already fixed the bug in your code.
For most software development, it’s not economically viable to catch every single possible bug before releasing a product to users. Sure, if you’re writing code for the space shuttle the downside of a bug is pretty big so you probably have a huge QA team and process, but for most mobile apps, it’s a numbers game. Catch as many significant bugs as you can before release, and make sure you can identify and fix bugs as quickly as possible after release.
HockeyApp is great for knowing when your app crashes, who’s affected and identifying the culprit code.
Rollout is a new service that lets you instantly deploy code-level changes to live native iOS apps, allowing you to fix bugs or contain issues immediately or dig deeper into your code if needed.
Together, they provide the perfect solution to support your Mobile DevOps process, for finding and fixing mobile app bugs in a matter of hours (or even minutes) and not days (or weeks).
Let’s look at an example of using HockeyApp together with Rollout to identify and fix a bug.
You’ve just released a new version of your game, 2049 version 1.2 (it’s a clone of 2048). Shortly after launch, your HockeyApp dashboard shows that version 1.2 has a crash rate of 1.97%, which is about four times worse than the previous crash rate of 0.49% — oh no!
Upon initial investigation in HockeyApp, you can see the app is crashing in the
restart: method, though you’re not able to replicate the crash on your own device.
Your crash stack trace shows the issue is related to the high-score tracking code, though you are not able to reproduce the issue in your local environment and need to investigate further.
FYI – The high score itself is called BEST in the app code and UI:
Adding Patch Code to Help With Debugging
You want to log the current values of
best when the
restart: method is called in order to debug the issue.
Using Rollout’s ability to modify methods on the fly, you create the following patch which is executed instead of the original method code. The original method is still accessible from within the patch code as in the example below.
With Rollout, your patch code can utilize any logging capabilities your app already has. For now, you want to send your log data into HockeyApp. For technical details on how to add application specific log data for into your crash report, check out HockeyApp’s help page.
The example app we’re using includes code based off of HockeyApp’s own example. Here is the code from AppDelegate.m which creates a MyLogger object we’ll use:
In the HockeyApp Dashboard if you look at the bottom of the Crash Logs section you’ll see underData you have three buttons: Log, Description and Meta. The log data we send to HockeyApp will appear in the Description section. Here is an example of what the description data looks like before we add the Rollout patch:
The following Rollout patch for the
restart: method is executed instead of the original method. It logs the current values of
best and whenever
restart: is called.
Lines 11 and 12 grab the current values of
Line 15 logs the values using the
Line 18 then executes the original
Rollout’s SDK makes a secure network request whenever the app is loaded (or when going from background to foreground) to see if there are any patches for your app and automatically applies the patch (no user intervention required).
Here’s what the description data looks like after the patch is applied:
In the log file above, when score = best (red arrows) it looks like the app is crashing because the next log entry is Application Started. When score != best (green arrow) it looks like the app didn’t crash.
Ah Ha! So now we know the crash is caused when the user restarts the game and the current score is the best score.
Fixing the Bug in Real-Time
Now what we know what’s causing the crash, we’ll update the patch and modify the value of the current score before we call the original method in order to avoid the crash (lines 15-18 below):
You immediately deploy the patch (only to users who are using version 1.2) and soon after see the crash rate drop down to 0.5% again. All is well.
From Bug Discovery to Fixed Production App, in a Matter of Hours
Using Rollout and HockeyApp together provides a next generation solution for mobile DevOps. Up until now you could only diagnose production issues. Now you can fix them as well.