2016-02-01 96 views
17

我的React Native应用程序想要在用户打开应用程序时将其本地数据与API同步。这应该在用户返回应用程序时发生,而不仅仅是在第一次启动时。从本质上讲,我想要的是相当于AppDelegate的回调函数applicationDidBecomeActive,这样我就可以在那里运行同步代码。很显然,我想在React Native中这样做。如何检测React Native应用程序何时打开?

据我所知,根组件上的componentWillMount/componentDidMount回调仅在最初加载应用程序时运行,而不是在用户离开应用程序并稍后返回(未明确退出应用程序)之后运行。

我认为AppState API会提供此功能,但其change侦听器在这种情况下也不会触发。

这似乎是明显的功能,所以我必须错过明显的东西。帮帮我!

+2

我目前正在使用react-native 0.26.3和'AppState'按iOS和Android的预期工作,所以似乎不再需要'AppStateIOS'。 –

+2

是的。看起来这是在最近版本的React Native中修复的。 – Mitch

+0

我用过appstate。它适用于模拟器,但使用真实的ios设备时事件不会被解雇。 – Waqas

回答

16

我通过使用AppStateIOS API而不是AppState来解决此问题。后者在iOS设备上按预期工作:当应用程序转到后台时,将触发"change"事件,并在该事件回到前台时再次发生。据我所知,在iOS设备上,AppState API似乎并没有触发"change"事件,如React Native v0.18。该项目的约定表明AppState应该是一个围绕AppStateIOS的跨平台包装,但在这里似乎并不是这样。

下面的例子说明了这个问题:

React.createClass({ 

    componentDidMount() { 
    AppStateIOS.addEventListener('change', state => 
     console.log('AppStateIOS changed to', state) 
    ) 

    AppState.addEventListener('change', state => 
     console.log('AppState changed to', state) 
    ) 
    }, 

    render() { 
    return <View/> 
    } 

}) 

当该组件被安装到一个阵营本机应用程序,你会看到关闭和打开应用程序时,“AppStateIOS改为...”。据我所知,您将从不请参阅“AppState更改为...”。

更新

看来,这是固定在阵营最近原住民(如V26的)。您现在可以使用在iOS和Android上宣传的AppState

0

我不认为你错过了什么。此功能仅仅是开箱即用的原生反应。也许这个想法是为了简化,因为对于大多数应用程序来说,当应用程序返回到前台时足以执行数据同步。

您可以创建自己的本机模块,它提供了这个功能,或者你可以用一个简单的(有点哈克的?)解决方案去:

在AppDelegate中保存的反应根视图的引用:

@interface AppDelegate() 
@property (nonatomic, strong) RCTRootView *rootView; 
@end 

当初始化视图,设置你的财产,并使用它:

self.rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 
              moduleName:@"MyApp" 
            initialProperties:nil 
             launchOptions:launchOptions]; 

现在实施处理像您激活状态W上的AppDelegate的方法在您的iOS应用乌尔德做和信息传递的道具:

-(void)onAppActiveStateChanged:(BOOL)appBecameActive 
{ 
    NSMutableDictionary *newProps = [NSMutableDictionary dictionary]; 
    if (self.rootView.appProperties != nil) { 
    [newProps addEntriesFromDictionary:self.rootView.appProperties]; 
    } 
    newProps[@"appDidBecomeActive"] = @(appBecameActive); 
    self.rootView.appProperties = newProps; 
} 

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    [self onAppActiveStateChanged:NO]; 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [self onAppActiveStateChanged:YES]; 
} 

在JavaScript端,做任何你需要的时候道具变化:

componentWillReceiveProps(nextProps) { 
    if (nextProps.appDidBecomeActive) { 
    alert('app did become active'); 
    } 
} 

我不知道这是否是最好的办法,但它应该工作...

0

我认为你已经回答了你的问题。为什么不使用componentWillMount和AppState - >'change'的组合?这应该涵盖所有情况。我使用它通过CodePush同步我的应用程序。

+0

不幸的是,据我所知,AppState - >'change''在用户打开或关闭应用程序时根本不会触发。所以我只能检测到应用程序首次启动时。 – Mitch

+1

嗯。根据我的经验它确实如此。我有AppStateIOS.addEventListener('更改',this.onAppStateChange);在我的根组件的componentDidMount方法中。每当我回到主屏幕或回来时它都会闪光。 –

+0

好的。感谢您的跟踪!我会再试一次并报告。 – Mitch

相关问题