Under the Hood: How We Patch Your Mobile App in Production
** This article is outdated and is no longer correct. **
Please see the following article which reflects our current technology:
Rollout Under the Hood – 2016 Update
So you just finished fixing a crucial bug in your new mobile app and submit it for approval. If you’ve done this before, you already know that this process can take anywhere from 3 days to 2 weeks! However, if you are experiencing an urgent issue with your app in production, even a few hours can be an unbearable amount of time to wait. Rollout.io allows you to hot patch critical bugs in iOS apps in production (it’s true!). Rather than waiting for AppStore approval to hot patch and fix bugs on your own, with Rollout.io, you can search for and fix problematic live code. This is done by controlling how an individual function is executed based on Rollout.io’s configuration. For example, you could wrap a function with try/catch, replace a specific argument, run the function from a different thread, and more use cases.
In this article, I will elaborate in detail on how Rollout.io works behind the scenes, abiding by Apple’s rules and regulations while not impacting your mobile app’s performance.
The heart of Rollout.io’s magic lies in a technique called method swizzling.
“Method swizzling is the process of changing the implementation of an existing selector. It’s a technique made possible by the fact that method invocations in Objective-C can be changed at runtime, by changing how selectors are mapped to underlying functions in a class’s dispatch table.
Swizzling enables Rollout.io to replace customers’ original functions with newly generated Rollout.io functions. For example, let’s say you have a function (we’ll call it Function A) that returns a nil value in certain scenarios. This causes your application to crash because the nil is pushed into an NSArray. Without Rollout.io, you would have to find the bug that is causing your application to crash, fix it, run your internal QA process and then send the fix to the AppStore for approval, which, as mentioned above, could take longer than you’d like. With Rollout.io, however, you can simply choose Function A and replace its nil value with an empty string. As mentioned above, this process of replacing the malfunctioning function is called method swizzling. Learn more about Rollout.io.
We use method swizzling to replace functions that malfunction with functions that perform configurable tasks. This is done without impacting performance or injecting dynamic code inside your app’s original code.
For those of you who have already installed Rollout.io, you might notice that we’ve added an additional phase to ‘Build Phases’. You can find it in the ‘Build Phases’ tab within your ‘Targets’. There, you will find the Rollout.io code analyzer –
The Rollout.io code analyzer reads your project file by using Ruby’s module – xcodeproj (https://github.com/CocoaPods/Xcodeproj – thank you cocoapods!) and runs a binary program that we developed using clang (the GCC replacement in Objective-C that Apple open sourced). Together with a little bit of bash scripting, the code analyzer produces a Rollout.io include dynamic file – RolloutSwizzlerDynamic.include. This file contains mirror functions of the ones that will be swizzled. In addition, the code analyzer generates a JSON file with the structure of your functions’ signatures, names and classes. The structure file is uploaded to Rollout.io’s server and is used by Rollout.io’s dashboard in order to allow you to select and configure a function’s hot patching.
Returning to our example above, you would configure your Rollout.io dashboard to replace Function A’s nil value with an empty string. Once you run Rollout.io’s set-up code, our SDK accesses the network end-point and fetches the hot patches that will be configured in your dashboard. We then verify if Function A needs to be replaced by a mirror function in Rollout.io’s dynamic include file, and follow through with the replacement using the swizzling mechanism. When the application then calls on Function A to perform a task, the mirror function will be executed instead. The mirror function then calls the original function and checks if the return value is nil, in which case, it would replace the value with an empty string.
You can run Rollout.io on your end without causing any performance issues. Rollout.io’s magic comes from activating mirror functions and executing swizzling, solely if a function’s original implementation needs to be hot patched.
Rollout.io’s dynamic include file (RolloutSwizzlerDynamic.include) is a static file of your application’s functions. The process of directly executing Function A, becomes the indirect process of executing Function B that then executes Function A. Swizzling fundamentally only adds another level to functions that are being pulled. If your environment doesn’t detect any hot patches, application runtime is not affected at all, and since we don’t incorporate swizzling into all of your functions, performance will not be impacted, either.
Another decision that we make concerns how Rollout.io’s SDK is loaded. The SDK is designed to help you solve mobile app issues as they happen. When your application starts, the SDK fetches any current configurations from Rollout.io’s end point, applying them immediately once they reach a device. This is done asynchronously so as to avoid any possible delays that may affect user experience. Lean more about our FAQs.
So, why did we choose this particular method? As mentioned above, one reason is because we kept performance in mind. Another reason is because Apple does not allow any code injections. Rollout.io holds a fixed set of optional patch configurations (e.g. try/catch or specific argument updates) that are essentially executed based on what you configure in the Rollout.io dashboard.
A similar approach is used by Facebook’s gatekeeper. The gatekeeper, which is a system that allows Facebook to roll out their features in a controlled fashion, works along the same lines as Rollout.io. It uses configurations to decide which buttons will appear or which codes will run without changing the application runtime (some call this feature toggling).
As you may know, any problem in computer science can be solved with another layer of indirection. We don’t inject any code to any files or functions. We don’t add or change problematic functions, either. As described above, we activate swizzling and actually execute the original function under a configuration wrapper that is set by you on your Rollout.io dashboard, letting you to decide whether or not you want to try/catch or run a function in its current thread or in the main thread. You could even call a different function instead of your original function, but the actual implementation stays the same.
This article only scratches the surface of Rollout.io’s mechanism. I decided to focus on hot patching in order to keep things simple and provide specific use cases. The ability to apply behavior on top of an application’s code provides our customers with interesting opportunities, such as ad hoc log generation (in order to track issues, even in production environments), dynamic analytics, A/B testing, remote configuration and more. Rollout.io is currently in its beta version, supporting hundreds of satisfied mobile app owners and developers that maintain applications running on millions of devices. There is no controversy with our solution from Apple’s AppStore, and we actually make running applications on Apple devices very neat and efficient. We have streamlined hot patches without harming the application delivery process or impacting end-users’ experiences . If you have not tried our solution yet, you can sign up for our beta version. If you are one of the hundreds currently using our services, we welcome you to write a comment below, and help us improve our product for you.
Rollout is an advanced feature management solution that gives engineering and product teams feature control, post-deployment. It’s the most effective way to roll out new features to the right audience while protecting customers from failure and improving KPI’s.