From 68b0ce657e81936d3b910ee9ea2f45d84deced9c Mon Sep 17 00:00:00 2001 From: Adam Comella Date: Tue, 12 Jul 2016 23:24:27 -0700 Subject: [PATCH] iOS: Provide correct initial value for AppState.currentState Summary: Attempt to fix #7919. Currently, if the app is launched into the background and you read `AppState.currentState` too soon, you will see the value `'active'` instead of `'background'`. This is because the default value of `AppState.currentState` is hardcoded to be `'active'` and it is initialized with the actual value asynchronously. This attempts to fix the bug by having the `RCTAppState` module provide the initial state as a module constant. As noted in #7919, it looks like this fix was already tried and reverted with 0fb3d8de83c4d8b79a8a110e9cd1300b39ab8918. zjj010104, hedgerwang, nicklockwood -- can you explain why? I would very much like to get this bug fixed. Nobody has followed up on the issue I filed so I decided to just go ahead and make a PR with my best guess at a fix. **Test plan (required)** Built a small app as described in the repro steps for #7919 and verified that, when the app is launched into the background, `init currentState: background` is printed. Also verified that `i Closes https://github.com/facebook/react-native/pull/8058 Differential Revision: D3554619 fbshipit-source-id: 5d950b85e335765552bbd3cf6ed91534062e35a1 --- Libraries/AppState/AppState.js | 14 ++++++-------- React/Modules/RCTAppState.m | 5 +++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index 1573a90129c..e8babe4dd61 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -83,12 +83,10 @@ class AppState extends NativeEventEmitter { memoryWarning: new Map(), }; - // TODO: getCurrentAppState callback seems to be called at a really late stage - // after app launch. Trying to get currentState when mounting App component - // will likely to have the initial value here. - // Initialize to 'active' instead of null. - this.currentState = 'active'; - + // TODO: Remove the 'active' fallback after `initialAppState` is exported by + // the Android implementation. + this.currentState = RCTAppState.initialAppState || 'active'; + // TODO: this is a terrible solution - in order to ensure `currentState` prop // is up to date, we have to register an observer that updates it whenever // the state changes, even if nobody cares. We should just deprecate the @@ -99,7 +97,7 @@ class AppState extends NativeEventEmitter { this.currentState = appStateData.app_state; } ); - + // TODO: see above - this request just populates the value of `currentState` // when the module is first initialized. Would be better to get rid of the prop // and expose `getCurrentAppState` method directly. @@ -111,7 +109,7 @@ class AppState extends NativeEventEmitter { ); } - /** + /** * Add a handler to AppState changes by listening to the `change` event type * and providing the handler * diff --git a/React/Modules/RCTAppState.m b/React/Modules/RCTAppState.m index db9716a7eff..1ae39027164 100644 --- a/React/Modules/RCTAppState.m +++ b/React/Modules/RCTAppState.m @@ -46,6 +46,11 @@ RCT_EXPORT_MODULE() return dispatch_get_main_queue(); } +- (NSDictionary *)constantsToExport +{ + return @{@"initialAppState": RCTCurrentAppBackgroundState()}; +} + #pragma mark - Lifecycle - (NSArray *)supportedEvents