diff --git a/Examples/UIExplorer/AppStateIOSExample.js b/Examples/UIExplorer/AppStateIOSExample.js
new file mode 100644
index 000000000..845b2e049
--- /dev/null
+++ b/Examples/UIExplorer/AppStateIOSExample.js
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule AppStateIOSExample
+ */
+'use strict';
+
+var React = require('react-native');
+var {
+ AppStateIOS,
+ Text,
+ View
+} = React;
+
+var AppStateSubscription = React.createClass({
+ getInitialState() {
+ return {
+ appState: AppStateIOS.currentState,
+ previousAppStates: [],
+ };
+ },
+ componentDidMount: function() {
+ AppStateIOS.addEventListener('change', this._handleAppStateChange);
+ },
+ componentWillUnmount: function() {
+ AppStateIOS.removeEventListener('change', this._handleAppStateChange);
+ },
+ _handleAppStateChange: function(appState) {
+ var previousAppStates = this.state.previousAppStates.slice();
+ previousAppStates.push(this.state.appState);
+ this.setState({
+ appState,
+ previousAppStates,
+ });
+ },
+ render() {
+ if (this.props.showCurrentOnly) {
+ return (
+
+ {this.state.appState}
+
+ );
+ }
+ return (
+
+ {JSON.stringify(this.state.previousAppStates)}
+
+ );
+ }
+});
+
+exports.title = 'AppStateIOS';
+exports.description = 'iOS app background status';
+exports.examples = [
+ {
+ title: 'AppStateIOS.currentState',
+ description: 'Can be null on app initialization',
+ render() { return {AppStateIOS.currentState}; }
+ },
+ {
+ title: 'Subscribed AppStateIOS:',
+ description: 'This changes according to the current state, so you can only ever see it rendered as "active"',
+ render() { return ; }
+ },
+ {
+ title: 'Previous states:',
+ render() { return ; }
+ },
+];
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index 456e76b63..ab8aed798 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -40,6 +40,7 @@ var EXAMPLES = [
require('./AsyncStorageExample'),
require('./CameraRollExample.ios'),
require('./MapViewExample'),
+ require('./AppStateIOSExample'),
require('./AdSupportIOSExample'),
require('./AppStateExample'),
];
diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js
index 691ab9d69..43b9db1a5 100644
--- a/Libraries/AppState/AppState.js
+++ b/Libraries/AppState/AppState.js
@@ -21,21 +21,9 @@ var AppState = {
getApplicationIconBadgeNumber: function(callback) {
RKAppState.getApplicationIconBadgeNumber(callback);
- }
-}
+ },
-AppState.backgroundStatus = new Subscribable(
- RCTDeviceEventEmitter,
- 'appStateDidChange',
- (resp) => resp.app_state,
- RKAppState.getCurrentAppState
-);
-
-AppState.BackgroundStatus = keyMirror({
- active: true,
- background: true,
- inactive: true,
-});
+};
// This check avoids redboxing if native RKReachability library isn't included in app
// TODO: Move reachability API into separate JS module to prevent need for this
diff --git a/Libraries/AppStateIOS/AppStateIOS.android.js b/Libraries/AppStateIOS/AppStateIOS.android.js
new file mode 100644
index 000000000..4bc7e691c
--- /dev/null
+++ b/Libraries/AppStateIOS/AppStateIOS.android.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule AppStateIOS
+ */
+'use strict';
+
+var warning = require('warning');
+
+class AppStateIOS {
+
+ static addEventListener(type, handler) {
+ warning('Cannot listen to AppStateIOS events on Android.');
+ }
+
+ static removeEventListener(type, handler) {
+ warning('Cannot remove AppStateIOS listener on Android.');
+ }
+
+}
+
+AppStateIOS.currentState = null;
+
+module.exports = AppStateIOS;
diff --git a/Libraries/AppStateIOS/AppStateIOS.ios.js b/Libraries/AppStateIOS/AppStateIOS.ios.js
new file mode 100644
index 000000000..8f03654b5
--- /dev/null
+++ b/Libraries/AppStateIOS/AppStateIOS.ios.js
@@ -0,0 +1,55 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule AppStateIOS
+ */
+'use strict';
+
+var NativeModules = require('NativeModules');
+var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
+var RKAppState = NativeModules.RKAppState;
+
+var logError = require('logError');
+
+var DEVICE_APPSTATE_EVENT = 'appStateDidChange';
+
+var _appStateHandlers = {};
+
+class AppStateIOS {
+
+ static addEventListener(type, handler) {
+ _appStateHandlers[handler] = RCTDeviceEventEmitter.addListener(
+ DEVICE_APPSTATE_EVENT,
+ (appStateData) => {
+ handler(appStateData.app_state);
+ }
+ );
+ }
+
+ static removeEventListener(type, handler) {
+ if (!_appStateHandlers[handler]) {
+ return;
+ }
+ _appStateHandlers[handler].remove();
+ _appStateHandlers[handler] = null;
+ }
+
+}
+
+AppStateIOS.currentState = null;
+
+RCTDeviceEventEmitter.addListener(
+ DEVICE_APPSTATE_EVENT,
+ (appStateData) => {
+ AppStateIOS.currentState = appStateData.app_state;
+ }
+);
+
+RKAppState.getCurrentAppState(
+ (appStateData) => {
+ AppStateIOS.currentState = appStateData.app_state;
+ },
+ logError
+);
+
+module.exports = AppStateIOS;
diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js
index 18c590c97..48217795f 100644
--- a/Libraries/react-native/react-native.js
+++ b/Libraries/react-native/react-native.js
@@ -11,6 +11,7 @@ var ReactNative = {
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
AppRegistry: require('AppRegistry'),
AppState: require('AppState'),
+ AppStateIOS: require('AppStateIOS'),
AsyncStorage: require('AsyncStorage'),
CameraRoll: require('CameraRoll'),
DatePickerIOS: require('DatePickerIOS'),