Using HockeyApp & Rollout to Find and Fix Live iOS App Bugs

Written by: ophir

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 bug-fix 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. CloudBees Feature Management 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 CloudBees Feature Management to identify and fix a bug.

Example Scenario

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 score and best when the restart: method is called in order to debug the issue. Using CloudBees Feature Management’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. Please Note: CloudBees Feature Management uses the iOS JavaScriptCore API to execute the patch code in native apps so all patches are written in JavaScript. With CloudBees Feature Management, 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: https://support.hockeyapp.net/kb/client-integration-ios-mac-os-x-tvos/how-to-add-application-specific-log-data-on-ios-or-os-x 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 under Data 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 CloudBees Feature Management patch:

The following CloudBees Feature Management patch for the restart: method is executed instead of the original method. It logs the current values of score and **best** and whenever restart: is called.

Lines 11 and 12 grab the current values of score and **best**. Line 15 logs the values using the MyLogger object. Line 18 then executes the original restart: method CloudBees Feature Management’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.

You might be asking yourself, is Apple OK with this? Isn’t it against Apple’s rules to bypass the App Store in order to update your app? Good question. The short answer is that CloudBees Feature Management is totally compliant with all of Apple’s guidelines. The guidelines say apps are not allowed to load code other than JavaScript (check) and that you’re not allowed to bypass the store to add new features or functionality (check). You can read a more detailed discussion of Apple’s guidelines for self-updating apps here. Using CloudBees Feature Management 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. If you’re an existing HockeyApp user and want to hear more about what CloudBees Feature Management can do for you, just contact us at support@rolllout.io

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.