From aad54006e3baebf94923b237dbc22c41fa985ac1 Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Fri, 22 May 2015 12:57:08 -0700 Subject: [PATCH] Observing "MemoryWarningNotification" and proxying it up to the DeviceEventEmitter --- Examples/UIExplorer/AppStateIOSExample.js | 18 ++++++++++ Libraries/AppStateIOS/AppStateIOS.ios.js | 41 ++++++++++++++++------- React/Modules/RCTAppState.m | 10 ++++++ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/Examples/UIExplorer/AppStateIOSExample.js b/Examples/UIExplorer/AppStateIOSExample.js index 9272f9e78..c2a011ceb 100644 --- a/Examples/UIExplorer/AppStateIOSExample.js +++ b/Examples/UIExplorer/AppStateIOSExample.js @@ -28,13 +28,19 @@ var AppStateSubscription = React.createClass({ return { appState: AppStateIOS.currentState, previousAppStates: [], + memoryWarnings: 0, }; }, componentDidMount: function() { AppStateIOS.addEventListener('change', this._handleAppStateChange); + AppStateIOS.addEventListener('memoryWarning', this._handleMemoryWarning); }, componentWillUnmount: function() { AppStateIOS.removeEventListener('change', this._handleAppStateChange); + AppStateIOS.removeEventListener('memoryWarning', this._handleMemoryWarning); + }, + _handleMemoryWarning: function() { + this.setState({memoryWarnings: this.state.memoryWarnings + 1}) }, _handleAppStateChange: function(appState) { var previousAppStates = this.state.previousAppStates.slice(); @@ -45,6 +51,13 @@ var AppStateSubscription = React.createClass({ }); }, render() { + if (this.props.showMemoryWarnings) { + return ( + + {this.state.memoryWarnings} + + ); + } if (this.props.showCurrentOnly) { return ( @@ -77,4 +90,9 @@ exports.examples = [ title: 'Previous states:', render(): ReactElement { return ; } }, + { + title: 'Memory Warnings', + description: "In the simulator, hit Shift+Command+M to simulate a memory warning.", + render(): ReactElement { return ; } + }, ]; diff --git a/Libraries/AppStateIOS/AppStateIOS.ios.js b/Libraries/AppStateIOS/AppStateIOS.ios.js index 48db8415b..b11c41a53 100644 --- a/Libraries/AppStateIOS/AppStateIOS.ios.js +++ b/Libraries/AppStateIOS/AppStateIOS.ios.js @@ -16,10 +16,12 @@ var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); var RCTAppState = NativeModules.AppState; var logError = require('logError'); +var invariant = require('invariant'); -var DEVICE_APPSTATE_EVENT = 'appStateDidChange'; - -var _appStateHandlers = {}; +var _eventHandlers = { + change: new Map(), + memoryWarning: new Map(), +}; /** * `AppStateIOS` can tell you if the app is in the foreground or background, @@ -82,12 +84,23 @@ var AppStateIOS = { type: string, handler: Function ) { - _appStateHandlers[handler] = RCTDeviceEventEmitter.addListener( - DEVICE_APPSTATE_EVENT, - (appStateData) => { - handler(appStateData.app_state); - } + invariant( + ['change', 'memoryWarning'].indexOf(type) !== -1, + 'Trying to subscribe to unknown event: "%s"', type ); + if (type === 'change') { + _eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener( + 'appStateDidChange', + (appStateData) => { + handler(appStateData.app_state); + } + )); + } else if (type === 'memoryWarning') { + _eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener( + 'memoryWarning', + handler + )); + } }, /** @@ -97,11 +110,15 @@ var AppStateIOS = { type: string, handler: Function ) { - if (!_appStateHandlers[handler]) { + invariant( + ['change', 'memoryWarning'].indexOf(type) !== -1, + 'Trying to remove listener for unknown event: "%s"', type + ); + if (!_eventHandlers[type].has(handler)) { return; } - _appStateHandlers[handler].remove(); - _appStateHandlers[handler] = null; + _eventHandlers[type].get(handler).remove(); + _eventHandlers[type].delete(handler); }, currentState: (null : ?String), @@ -109,7 +126,7 @@ var AppStateIOS = { }; RCTDeviceEventEmitter.addListener( - DEVICE_APPSTATE_EVENT, + 'appStateDidChange', (appStateData) => { AppStateIOS.currentState = appStateData.app_state; } diff --git a/React/Modules/RCTAppState.m b/React/Modules/RCTAppState.m index 9743e5042..8c46655c6 100644 --- a/React/Modules/RCTAppState.m +++ b/React/Modules/RCTAppState.m @@ -53,11 +53,21 @@ RCT_EXPORT_MODULE() selector:@selector(handleAppStateDidChange) name:name object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleMemoryWarning) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; } } return self; } +- (void)handleMemoryWarning +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"memoryWarning" + body:nil]; +} - (void)dealloc {