Merge pull request #431 from Microsoft/codepushify

Add @codePush decorator
This commit is contained in:
Geoffrey Goh
2016-08-02 16:07:37 -07:00
committed by GitHub
3 changed files with 281 additions and 39 deletions

View File

@@ -3,7 +3,7 @@ import { Alert } from "./AlertAdapter";
import requestFetchAdapter from "./request-fetch-adapter";
import { AppState, Platform } from "react-native";
import RestartManager from "./RestartManager";
import log from './logging';
import log from "./logging";
let NativeCodePush = require("react-native").NativeModules.CodePush;
const PackageMixins = require("./package-mixins")(NativeCodePush);
@@ -401,12 +401,58 @@ async function syncInternal(options = {}, syncStatusChangeCallback, downloadProg
let CodePush;
function codePushify(options = {}) {
return (RootComponent) => {
let React;
let ReactNative = require("react-native");
try { React = require("react"); } catch (e) { }
if (!React) {
try { React = ReactNative.React; } catch (e) { }
if (!React) {
throw new Error("Unable to find the 'React' module.");
}
}
if (!React.Component) {
throw new Error(
`Unable to find the "Component" class, please either:
1. Upgrade to a newer version of React Native that supports it, or
2. Call the codePush.sync API in your component instead of using the @codePush decorator`
);
}
return class CodePushComponent extends React.Component {
componentDidMount() {
if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {
CodePush.notifyAppReady();
} else {
let rootComponentInstance = this.refs.rootComponent;
let syncStatusCallback = rootComponentInstance && rootComponentInstance.codePushStatusDidChange;
let downloadProgressCallback = rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress;
CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {
ReactNative.AppState.addEventListener("change", (newState) => {
newState === "active" && CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
});
}
}
}
render() {
return <RootComponent {...this.props} ref={"rootComponent"} />
}
}
}
}
// If the "NativeCodePush" variable isn't defined, then
// the app didn't properly install the native module,
// and therefore, it doesn't make sense initializing
// the JS interface when it wouldn't work anyways.
if (NativeCodePush) {
CodePush = {
CodePush = codePushify;
Object.assign(CodePush, {
AcquisitionSdk: Sdk,
checkForUpdate,
getConfiguration,
@@ -436,6 +482,11 @@ if (NativeCodePush) {
DOWNLOADING_PACKAGE: 7,
INSTALLING_UPDATE: 8
},
CheckFrequency: {
ON_APP_START: 0,
ON_APP_RESUME: 1,
MANUAL: 2
},
UpdateState: {
RUNNING: NativeCodePush.codePushUpdateStateRunning,
PENDING: NativeCodePush.codePushUpdateStatePending,
@@ -455,7 +506,7 @@ if (NativeCodePush) {
optionalUpdateMessage: "An update is available. Would you like to install it?",
title: "Update available"
}
};
});
} else {
log("The CodePush module doesn't appear to be properly installed. Please double-check that everything is setup correctly.");
}

228
README.md
View File

@@ -420,33 +420,76 @@ With the CodePush plugin downloaded and linked, and your app asking CodePush whe
2. When an update is available, how to present it to the end user?
The simplest way to do this is to perform the following in your app's root component:
The simplest way to do this is to "CodePush-ify" your app's root component. To do so, you can choose one of the following two options:
1. Import the JavaScript module for CodePush:
* **Option 1: Wrap your root component with the `codePush` higher-order component:**
```javascript
import codePush from "react-native-code-push";
let codePushOptions;
class MyApp extends Component {
}
MyApp = codePush(codePushOptions)(MyApp);
```
2. Call the `sync` method from within the `componentDidMount` lifecycle event, to initiate a background update on each app start:
* **Option 2: Use the [ES7 decorator](https://github.com/wycats/javascript-decorators) syntax:**
*NOTE: Decorators are not yet supported in Babel 6.x pending proposal update.* You may need to enable it by installing and using [babel-preset-react-native-stage-0](https://github.com/skevy/babel-preset-react-native-stage-0#babel-preset-react-native-stage-0).
```javascript
codePush.sync();
import codePush from "react-native-code-push";
let codePushOptions;
@codePush(codePushOptions)
class MyApp extends Component {
}
```
If an update is available, it will be silently downloaded, and installed the next time the app is restarted (either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. If an available update is mandatory, then it will be installed immediately, ensuring that the end user gets it as soon as possible.
By default, CodePush will check for updates on every app start. If an update is available, it will be silently downloaded, and installed the next time the app is restarted (either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. If an available update is mandatory, then it will be installed immediately, ensuring that the end user gets it as soon as possible.
If you would like your app to discover updates more quickly, you can also choose to call `sync` every time the app resumes from the background, by adding the following code (or something equivalent) as part of your app's startup behavior (e.g. your root component's `componentDidMount` method). You can call `sync` as frequently as you would like, so when and where you call it just depends on your personal preference.
If you would like your app to discover updates more quickly, you can also choose to sync up with the CodePush server every time the app resumes from the background.
```javascript
AppState.addEventListener("change", (newState) => {
newState === "active" && codePush.sync();
});
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
class MyApp extends Component {
}
MyApp = codePush(CodePushOptions)(MyApp);
```
*NOTE: If you are using [Redux](http://redux.js.org) and [Redux Saga](http://yelouafi.github.io/redux-saga/), you can alternatively use the [react-native-code-push-saga](http://github.com/lostintangent/react-native-code-push-saga) module, which allows you to customize when `sync` is called in simpler/more idiomatic way.*
Alternatively, if you want fine-grained control over when the check happens (e.g. a button press or timer interval), you can call [`CodePush.sync()`](#codepushsync) at any time with your desired `SyncOptions`, and optionally turn off CodePush's automatic checking by specifying a manual `checkFrequency`:
Additionally, if you would like to display an update confirmation dialog (an "active install"), configure when an available update is installed (e.g. force an immediate restart) or customize the update experience in any way, refer to the `sync` method's [API reference](#codepushsync) for information on how to tweak this default behavior.
```javascript
let codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
class MyApp extends Component {
onButtonPress() {
codePush.sync({
updateDialog: true,
installMode: codePush.installMode.IMMEDIATE
});
}
render() {
<View>
<TouchableOpacity onPress={this.onButtonPress}>
<Text>Check for updates</Text>
</TouchableOpacity>
</View>
}
}
MyApp = codePush(CodePushOptions)(MyApp);
```
If you would like to display an update confirmation dialog (an "active install"), configure when an available update is installed (e.g. force an immediate restart) or customize the update experience in any other way, refer to the [`codePush()`](#codepush) API reference for information on how to tweak this default behavior.
*NOTE: If you are using [Redux](http://redux.js.org) and [Redux Saga](http://yelouafi.github.io/redux-saga/), you can alternatively use the [react-native-code-push-saga](http://github.com/lostintangent/react-native-code-push-saga) module, which allows you to customize when `sync` is called in a perhaps simpler/more idiomatic way.*
<a id="apple-note">*NOTE: While [Apple's developer agreement](https://developer.apple.com/programs/ios/information/iOS_Program_Information_4_3_15.pdf) fully allows performing over-the-air updates of JavaScript and assets (which is what enables CodePush!), it is against their policy for an app to display an update prompt. Because of this, we recommend that App Store-distributed apps don't enable the `updateDialog` option when calling `sync`, whereas Google Play and internally distributed apps (e.g. Enterprise, Fabric, HockeyApp) can choose to enable/customize it.*</a>
@@ -616,7 +659,7 @@ Additionally, if you want to give them seperate names and/or icons, you can modi
The above section illustrated how you can leverage multiple CodePush deployments in order to effectively test your updates before broadly releasing them to your end users. However, since that workflow statically embeds the deployment assignment into the actual binary, a staging or production build will only ever sync updates from that deployment. In many cases, this is sufficient, since you only want your team, customers, stakeholders, etc. to sync with your pre-production releases, and therefore, only they need a build that knows how to sync with staging. However, if you want to be able to perform A/B tests, or provide early access of your app to certain users, it can prove very useful to be able to dynamically place specific users (or audiences) into specific deployments at runtime.
In order to achieve this kind of workflow, all you need to do is specify the deployment key you want the current user to syncronize with when calling the `checkForUpdate` or `sync` methods. When specified, this key will override the "default" one that was provided in your app's `Info.plist` (iOS) or `MainActivity.java` (Android) files. This allows you to produce a build for staging or production, that is also capabable of being dynamically "redirected" as needed.
In order to achieve this kind of workflow, all you need to do is specify the deployment key you want the current user to syncronize with when calling the `codePush` method. When specified, this key will override the "default" one that was provided in your app's `Info.plist` (iOS) or `MainActivity.java` (Android) files. This allows you to produce a build for staging or production, that is also capable of being dynamically "redirected" as needed.
```javascript
// Imagine that "userProfile" is a prop that this component received
@@ -664,6 +707,8 @@ When you require `react-native-code-push`, the module object provides the follow
* [checkForUpdate](#codepushcheckforupdate): Asks the CodePush service whether the configured app deployment has an update available.
* [codePushify](#codepushcodepushify): Returns a function that wraps a React component inside a "higher order" React component configured to call [`codePush.sync()`](#codepushsync) when it is mounted. This allows you to declaratively specify the behaviour of how and when your app checks for an update, downloads it and installs it.
* [disallowRestart](#codepushdisallowrestart): Temporarily disallows any programmatic restarts to occur as a result of a CodePush update being installed. This is an advanced API, and is useful when a component within your app (e.g. an onboarding process) needs to ensure that no end-user interruptions can occur during its lifetime.
* [getCurrentPackage](#codepushgetcurrentpackage): Retrieves the metadata about the currently installed update (e.g. description, installation time, size). *NOTE: As of `v1.10.3-beta` of the CodePush module, this method is deprecated in favor of [`getUpdateMetadata`](#codepushgetupdatemetadata)*.
@@ -676,6 +721,123 @@ When you require `react-native-code-push`, the module object provides the follow
* [sync](#codepushsync): Allows checking for an update, downloading it and installing it, all with a single call. Unless you need custom UI and/or behavior, we recommend most developers to use this method when integrating CodePush into their apps
#### codePush
```javascript
codePush(options: CodePushOptions)(rootComponent: React.Component): React.Component;
```
Used as a decorator to wrap a React component inside a "higher order" React component that knows how to synchronize your app's JavaScript bundle and image assets with the latest release to the configured deployment when it is mounted. Internally, the wrapper component calls [`sync`](#codepushsync) inside its `componentDidMount` lifecycle handle, which in turns performs an update check, downloads the update if it exists and installs the update for you.
This decorator provides support for letting you customize its behaviour to easily enable apps with different requirements. Below are some examples of ways you can use it (you can pick one or even use a combination):
1. **Silent sync on app start** *(the simplest, default behavior)*. Your app will automatically download available updates, and apply them the next time the app restarts (e.g. the OS or end user killed it, or the device was restarted). This way, the entire update experience is "silent" to the end user, since they don't see any update prompt and/or "synthetic" app restarts.
```javascript
// Fully silent update which keeps the app in
// sync with the server, without ever
// interrupting the end user
@codePush()
class MyApp extends Component {}
```
2. **Silent sync everytime the app resumes**. Same as 1, except we check for updates, or apply an update if one exists every time the app returns to the foreground after being "backgrounded".
```javascript
// Sync for updates everytime the app resumes.
@codePush({ checkFrequency: codePush.CheckFrequency.ON_APP_RESUME, installMode: codePush.InstallMode.ON_NEXT_RESUME })
class MyApp extends Component {}
```
3. **Interactive**. When an update is available, prompt the end user for permission before downloading it, and then immediately apply the update. If an update was released using the `mandatory` flag, the end user would still be notified about the update, but they wouldn't have the choice to ignore it.
```javascript
// Active update, which lets the end user know
// about each update, and displays it to them
// immediately after downloading it
@codePush({ updateDialog: true, installMode: codePush.InstallMode.IMMEDIATE })
class MyApp extends Component {}
```
4. **Log/display progress**. While the app is syncing with the server for updates, make use of the `codePushStatusDidChange` and/or `codePushDownloadDidProgress` event hooks to log down the different stages of this process, or even display a progress bar to the user.
```javascript
// Make use of the event hooks to keep track of
// the different stages of the sync process.
@codePush()
class MyApp extends Component {
codePushStatusDidChange(status) {
switch(syncStatus) {
case codePush.SyncStatus.CHECKING_FOR_UPDATE:
console.log("Checking for updates.");
break;
case codePush.SyncStatus.DOWNLOADING_PACKAGE:
console.log("Downloading package.");
break;
case codePush.SyncStatus.INSTALLING_UPDATE:
console.log("Installing update.");
break;
case codePush.SyncStatus.UP_TO_DATE:
console.log("Installing update.");
break;
case codePush.SyncStatus.UPDATE_INSTALLED:
console.log("Update installed.");
break;
}
}
codePushDownloadDidProgress(progress) {
console.log(progess.receivedBytes + " of " + progress.totalBytes + " received.");
}
}
```
##### CodePushOptions
The `codePush` decorator accepts an "options" object that allows you to customize numerous aspects of the default behavior mentioned above:
* __checkFrequency__ *(codePush.CheckFrequency)* - Specifies when you would like to check for updates. Defaults to `codePush.CheckFrequency.ON_APP_START`. Refer to the [`CheckFrequency`](#checkfrequency) enum reference for a description of the available options and what they do.
* __deploymentKey__ *(String)* - Specifies the deployment key you want to query for an update against. By default, this value is derived from the `Info.plist` file (iOS) and `MainActivity.java` file (Android), but this option allows you to override it from the script-side if you need to dynamically use a different deployment.
* __installMode__ *(codePush.InstallMode)* - Specifies when you would like to install optional updates (i.e. those that aren't marked as mandatory). Defaults to `codePush.InstallMode.ON_NEXT_RESTART`. Refer to the [`InstallMode`](#installmode) enum reference for a description of the available options and what they do.
* __mandatoryInstallMode__ *(codePush.InstallMode)* - Specifies when you would like to install updates which are marked as mandatory. Defaults to `codePush.InstallMode.IMMEDIATE`. Refer to the [`InstallMode`](#installmode) enum reference for a description of the available options and what they do.
* __minimumBackgroundDuration__ *(Number)* - Specifies the minimum number of seconds that the app needs to have been in the background before restarting the app. This property only applies to updates which are installed using `InstallMode.ON_NEXT_RESUME`, and can be useful for getting your update in front of end users sooner, without being too obtrusive. Defaults to `0`, which has the effect of applying the update immediately after a resume, regardless how long it was in the background.
* __updateDialog__ *(UpdateDialogOptions)* - An "options" object used to determine whether a confirmation dialog should be displayed to the end user when an update is available, and if so, what strings to use. Defaults to `null`, which has the effect of disabling the dialog completely. Setting this to any truthy value will enable the dialog with the default strings, and passing an object to this parameter allows enabling the dialog as well as overriding one or more of the default strings. Before enabling this option within an App Store-distributed app, please refer to [this note](#user-content-apple-note).
The following list represents the available options and their defaults:
* __appendReleaseDescription__ *(Boolean)* - Indicates whether you would like to append the description of an available release to the notification message which is displayed to the end user. Defaults to `false`.
* __descriptionPrefix__ *(String)* - Indicates the string you would like to prefix the release description with, if any, when displaying the update notification to the end user. Defaults to `" Description: "`
* __mandatoryContinueButtonLabel__ *(String)* - The text to use for the button the end user must press in order to install a mandatory update. Defaults to `"Continue"`.
* __mandatoryUpdateMessage__ *(String)* - The text used as the body of an update notification, when the update is specified as mandatory. Defaults to `"An update is available that must be installed."`.
* __optionalIgnoreButtonLabel__ *(String)* - The text to use for the button the end user can press in order to ignore an optional update that is available. Defaults to `"Ignore"`.
* __optionalInstallButtonLabel__ *(String)* - The text to use for the button the end user can press in order to install an optional update. Defaults to `"Install"`.
* __optionalUpdateMessage__ *(String)* - The text used as the body of an update notification, when the update is optional. Defaults to `"An update is available. Would you like to install it?"`.
* __title__ *(String)* - The text used as the header of an update notification that is displayed to the end user. Defaults to `"Update available"`.
##### codePushStatusDidChange (event hook)
Called when the sync process moves from one stage to another in the overall update process. The event hook is called with a status code which represents the current state, and can be any of the [`SyncStatus`](#syncstatus) values.
##### codePushDownloadDidProgress (event hook)
Called periodically when an available update is being downloaded from the CodePush server. The method is called with a `DownloadProgress` object, which contains the following two properties:
* __totalBytes__ *(Number)* - The total number of bytes expected to be received for this update (i.e. the size of the set of files which changed from the previous release).
* __receivedBytes__ *(Number)* - The number of bytes downloaded thus far, which can be used to track download progress.
#### codePush.allowRestart
```javascript
@@ -907,35 +1069,19 @@ codePush.sync({ updateDialog: true, installMode: codePush.InstallMode.IMMEDIATE
*Note: If you want to decide whether you check and/or download an available update based on the end user's device battery level, network conditions, etc. then simply wrap the call to `sync` in a condition that ensures you only call it when desired.*
While the `sync` method tries to make it easy to perform silent and active updates with little configuration, it accepts an "options" object that allows you to customize numerous aspects of the default behavior mentioned above:
##### SyncOptions
* __deploymentKey__ *(String)* - Specifies the deployment key you want to query for an update against. By default, this value is derived from the `Info.plist` file (iOS) and `MainActivity.java` file (Android), but this option allows you to override it from the script-side if you need to dynamically use a different deployment for a specific call to `sync`.
While the `sync` method tries to make it easy to perform silent and active updates with little configuration, it accepts an "options" object that allows you to customize numerous aspects of the default behavior mentioned above. The options available are identical to the [CodePushOptions](#codepushoptions), with the exception of the `checkFrequency` option:
* __installMode__ *(codePush.InstallMode)* - Specifies when you would like to install optional updates (i.e. those that aren't marked as mandatory). Defaults to `codePush.InstallMode.ON_NEXT_RESTART`. Refer to the [`InstallMode`](#installmode) enum reference for a description of the available options and what they do.
* __deploymentKey__ *(String)* - Refer to [`CodePushOptions`](#codepushoptions).
* __mandatoryInstallMode__ *(codePush.InstallMode)* - Specifies when you would like to install updates which are marked as mandatory. Defaults to `codePush.InstallMode.IMMEDIATE`. Refer to the [`InstallMode`](#installmode) enum reference for a description of the available options and what they do.
* __installMode__ *(codePush.InstallMode)* - Refer to [`CodePushOptions`](#codepushoptions).
* __minimumBackgroundDuration__ *(Number)* - Specifies the minimum number of seconds that the app needs to have been in the background before restarting the app. This property only applies to updates which are installed using `InstallMode.ON_NEXT_RESUME`, and can be useful for getting your update in front of end users sooner, without being too obtrusive. Defaults to `0`, which has the effect of applying the update immediately after a resume, regardless how long it was in the background.
* __mandatoryInstallMode__ *(codePush.InstallMode)* - Refer to [`CodePushOptions`](#codepushoptions).
* __updateDialog__ *(UpdateDialogOptions)* - An "options" object used to determine whether a confirmation dialog should be displayed to the end user when an update is available, and if so, what strings to use. Defaults to `null`, which has the effect of disabling the dialog completely. Setting this to any truthy value will enable the dialog with the default strings, and passing an object to this parameter allows enabling the dialog as well as overriding one or more of the default strings. Before enabling this option within an App Store-distributed app, please refer to [this note](#user-content-apple-note).
* __minimumBackgroundDuration__ *(Number)* - Refer to [`CodePushOptions`](#codepushoptions).
The following list represents the available options and their defaults:
* __appendReleaseDescription__ *(Boolean)* - Indicates whether you would like to append the description of an available release to the notification message which is displayed to the end user. Defaults to `false`.
* __descriptionPrefix__ *(String)* - Indicates the string you would like to prefix the release description with, if any, when displaying the update notification to the end user. Defaults to `" Description: "`
* __mandatoryContinueButtonLabel__ *(String)* - The text to use for the button the end user must press in order to install a mandatory update. Defaults to `"Continue"`.
* __mandatoryUpdateMessage__ *(String)* - The text used as the body of an update notification, when the update is specified as mandatory. Defaults to `"An update is available that must be installed."`.
* __optionalIgnoreButtonLabel__ *(String)* - The text to use for the button the end user can press in order to ignore an optional update that is available. Defaults to `"Ignore"`.
* __optionalInstallButtonLabel__ *(String)* - The text to use for the button the end user can press in order to install an optional update. Defaults to `"Install"`.
* __optionalUpdateMessage__ *(String)* - The text used as the body of an update notification, when the update is optional. Defaults to `"An update is available. Would you like to install it?"`.
* __title__ *(String)* - The text used as the header of an update notification that is displayed to the end user. Defaults to `"Update available"`.
* __updateDialog__ *(UpdateDialogOptions)* - Refer to [`CodePushOptions`](#codepushoptions).
Example Usage:
@@ -1069,6 +1215,16 @@ This enum specifies when you would like an installed update to actually be appli
* __codePush.InstallMode.ON_NEXT_RESUME__ *(2)* - Indicates that you want to install the update, but don't want to restart the app until the next time the end user resumes it from the background. This way, you don't disrupt their current session, but you can get the update in front of them sooner then having to wait for the next natural restart. This value is appropriate for silent installs that can be applied on resume in a non-invasive way.
##### CheckFrequency
This enum specifies when you would like your app to sync with the server for updates, and can be passed to the `codePushify` decorator. It includes the following values:
* __codePush.CheckFrequency.ON_APP_START__ *(0)* - Indicates that you want to check for updates whenever the app's process is started.
* __codePush.CheckFrequency.ON_APP_RESUME__ *(1)* - Indicates that you want to check for updates whenever the app is brought back to the foreground after being "backgrounded" (user pressed the home button, app launches a seperate payment process, etc).
* __codePush.CheckFrequency.MANUAL__ *(2)* - Disable automatic checking for updates, but only check when [`codePush.sync()`](#codepushsync) is called in app code.
##### SyncStatus
This enum is provided to the `syncStatusChangedCallback` function that can be passed to the `sync` method, in order to hook into the overall update process. It includes the following values:
@@ -1175,7 +1331,7 @@ The `sync` method includes a lot of diagnostic logging out-of-the-box, so if you
The simplest way to view these logs is to run the `code-push debug` command for the specific platform you are currently working with (e.g. `code-push debug ios`). This will output a log stream that is filtered to just CodePush messages, for the specified platform. This makes it easy to identify issues, without needing to use a platform-specific tool, or wade through a potentially high volume of logs.
<img width="540" alt="screen shot 2016-06-21 at 10 15 42 am" src="https://cloud.githubusercontent.com/assets/116461/16246973/838e2e98-37bc-11e6-9649-685f39e325a0.png">
Additionally, you can also use any of the platform-specific tools to view the CodePush logs, if you are more comfortable with them. Simple start up the Chrome DevTools Console, the Xcode Console (iOS), the [OS X Console](https://en.wikipedia.org/wiki/Console_%28OS_X%29#.7E.2FLibrary.2FLogs) (iOS) and/or ADB logcat (Android), and look for messages which are prefixed with `[CodePush]`.
Note that by default, React Native logs are disabled on iOS in release builds, so if you want to view them in a release build, you need to make the following changes to your `AppDelegate.m` file:

View File

@@ -20,6 +20,14 @@ interface Promise<T> {
export type DowloadProgressCallback = (progress: DownloadProgress) => void;
export type SyncStatusChangedCallback = (status: CodePush.SyncStatus) => void;
export interface CodePushOptions extends SyncOptions {
/**
* Specifies when you would like to synchronize updates with the CodePush server.
* Defaults to codePush.CheckFrequency.ON_APP_START.
*/
checkFrequency: CodePush.CheckFrequency;
}
export interface DownloadProgress {
/**
* The total number of bytes expected to be received for this update.
@@ -219,6 +227,13 @@ export interface StatusReport {
previousLabelOrAppVersion?: string;
}
/**
* Decorates a React Component configuring it to sync for updates with the CodePush server.
*
* @param options Options used to configure the end-user sync and update experience (e.g. when to check for updates?, show an prompt?, install the update immediately?).
*/
declare function CodePush(options?: CodePushOptions): Function;
declare namespace CodePush {
/**
* Represents the default settings that will be used by the sync method if
@@ -383,6 +398,26 @@ declare namespace CodePush {
*/
SUCCEEDED
}
/**
* Indicates when you would like to check for (and install) updates from the CodePush server.
*/
enum CheckFrequency {
/**
* When the app is fully initialized (or more specifically, when the root component is mounted).
*/
ON_APP_START,
/**
* When the app re-enters the foreground.
*/
ON_APP_RESUME,
/**
* Don't automatically check for updates, but only do it when codePush.sync() is manully called inside app code.
*/
MANUAL
}
}
export default CodePush;