reload: Push updates to deployed apps

Trigger.io Reload allows you to update the HTML, CSS and JavaScript in your app for your users without you needing to push an App Store update or your users needing to re-install the app.

The reload option must be enabled in your App Config. Once the reload option is enabled you will be able to push updates to any builds of your app from that point.

Concepts

You can reload updates via the Toolkit UI, command-line or standalone build API.

You can reload all of your users, or divide them into streams for A/B testing.

You can use the default update behavior without altering your code at all beyond activating reload in the configuration. Or you can use the JavaScript API described here to have finer grain control over how reloads occur in your app.

You can Reload your app with up to 250Mb of content via Trigger.io. You can Reload your app with larger content hosted in a 3rd party CDN like Rackspace Cloud Files.

How Reloads work

When you reload a new version of your code through the Toolkit UI, users will see the new version of your code when they switch away from your app and switch back to it: we download updated files when focus is lost and apply the changes when focus is restored.

You have control over this process using the JavaScript API described here, but the default behavior does not require any change to your app's logic.

Streams

Streams let you segment your user base so that not everyone has to receive every update you push with Reload. This is useful for pushing regular unstable updates to developers, release candidates to beta testers and stable versions to the wider user base.

By default, your users are added to the 'default' stream - you can create as many streams as you want, and switch apps to different streams using using the switchStream method described below.

Config versions

You must only reload HTML / CSS and JavaScript where it works with the minor version of the Forge platform which you originally built against.

Reload Concepts

If your updated JavaScript relies on Forge APIs that are only available in newer versions of the wrapper than your users currently have installed, then you will need to re-package your apps and deploy through the app stores again.

API

In order to use reload no API calls are required, however some apps may which to use the following API methods to force updates at a users request, or switch the user to an alternate streams.

forge.reload.updateAvailable(success, error)

iOS, Android

The first argument in the success callback gives true or false depending on whether there is a reload update available to be downloaded.

Parameters:
success
function(update_available) called with whether or not an update is available
error
function(content) called with details of any error which may occur

forge.reload.update(success, error)

iOS, Android

Forces the application to check for, and if available download a reload update. The update will then be applied the next time the app is closed or loses focus.

Parameters:
success
function() called when an update is available and the download has started - see the updateReady event to be notified when the update is complete update available to be downloaded
error
function(content) called with details of any error which may occur

Note: If you have previously called pauseUpdate, this will override that and continue Reload updates - including any in-progress updates if applicable.

forge.reload.pauseUpdate(success, error)

iOS, Android

If there is a Reload update in-progress (i.e. downloading files), we will halt downloading after the current file has been received.

Parameters:
success
function() called when the Reload updates have been successfully paused
error
function(content) called with details of any error which may occur

Warning: Reload updates will not be downloaded for this app until you explicitly call update. Re-installing the app via the Toolkit (during development) or via an app store (in production) will also re-enable Reload updates.

forge.reload.applyAndRestartApp(success, error)

iOS, Android

When a Reload update has been fully downloaded (see updateReady event), calling this API method will refresh your app with the new files and navigate to index.html.

Parameters:
success
function() may be called before the app restarts - not recommended you put important code here, however, as the app might have stopped before we can invoke it
error
function(content) called with details of any error which may occur

forge.reload.switchStream(stream_name, success, error)

iOS, Android

Switches the reload stream the app will download updates from.

Parameters:
stream_name
string name to identify the stream
success
function() stream switched
error
function(content) called with details of any error which may occur

forge.reload.updateProgress.addListener(callback, error)

iOS, Android

Fired as a Reload update is being downloaded: your callback will be invoked as each file is received. We recommend the use of the updateReady event for detecting the full readiness of a Reload update.

Parameters:
callback
function(progress) progress is a hash with total and completed keys, e.g. {total: 10, completed: 5}. total is the total number of files we will download during this update; completed is how many files we've downloaded so far.
error
function(content) called with details of any error which may occur

forge.reload.updateReady.addListener(callback, error)

iOS, Android

Fired when a Reload update has been downloaded and is ready to apply.

Parameters:
callback
function() an update will be applied next time the app resumes
error
function(content) called with details of any error which may occur

Example:

forge.reload.updateAvailable(function(reloadIsAvailable) {
    // Checks to see if an update is available.
    if (reloadIsAvailable) {
        // We have an incoming reload, start update
        forge.reload.update(function () {
            forge.logging.info("Downloading update...");
            forge.reload.updateProgress.addListener(function (progress) {
                // Update app UI with a progress bar or somesuch
            });
            forge.reload.updateReady.addListener(function () {
                // Reload download is complete, apply it and restart app
                forge.reload.applyAndRestartApp();
            });
        });
    } else {
        forge.logging.info("No reload available.");
        // proceed with normal app startup
    }
});

Update process

The reload update process has several parts. First, it must be determined if an update is available, and if it is available it needs to be downloaded. Once an update has been downloaded it has to be applied, this means making the new files available to the app. If the app is running while an update is applied then there may need to be additional code in the app to make use of the updated files.

The following things will cause reload to download new update files if available:

  • A call to forge.reload.update().
  • On all platforms new files will be downloaded shortly after the app is launched.
  • On Android and iOS new files will also be downloaded when the app loses focus but is running in the background.
  • On Android new files will also be downloaded when the app exits.

Assuming an update has been fully downloaded and is ready to apply the following things will replace the apps assets files with the new update:

  • On all platforms when the app is relaunched (i.e. when it has been quit and opened again).
  • On iOS and Android when the app is restored from the background.
  • Usage of forge.reload.applyAndRestartApp.

If updates are applied during launching or restoring an app index.html will be reloaded with the new update files.

Notes

  • See Using Trigger.io Reload for more information about how to use Reload
  • Updates may take some time if the user is on a slow network, however several things are done to improve this, only changed files are downloaded in an update, and if an update is interrupted part way through it will resume where it left off next time it is started.
  • On iOS updates are given 10 minutes to download each time the app is paused as this is the maximum amount of background processing time available on iOS. If an update is interrupted it will resume where it left off on the next attempt.
  • Only one update is downloaded at a time, if an update is waiting to be applied any future updates will not be downloaded until it has been applied to the app. This should never be a problem for real users but may be confusing during testing.
  • When testing the easiest way to cause an update is to leave the app by pressing the home button on the device, wait a few seconds (or look at the log output to see when the reload update is complete), and reopen the app to see the update applied.

Important: Currently, pushing a Reload update will cause iOS devices to copy files out of the installed app bundle into a secondary area. This is due to sandboxing rules which prevent us directly accessing files in your installed app after a Reload has been completed. In order to avoid your app taking too much storage space on the device, it's recommended you distribute larger files using something like forge.file.saveURL, rather than including them in the app bundle.