React Native | 原生IOS模块与JS通信,监听App被Kill

4,118 阅读2分钟

一、创建原生模块

先按这个文档: React Native | 创建IOS原生模块创建一个RNGlobalManager原生模块。

image.png

二、编写原生模块

这里可以根据官网React Native官网 - IOS原生模块 来进行编写,我这里代码如下:

1.RNGlobalManager.h

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>


@interface RNGlobalManager : RCTEventEmitter <RCTBridgeModule>

- (void)sendEvent:(NSString *)eventName;
@end

2.RNGlobalManager.m

#import "RNGlobalManager.h"
#import <React/RCTLog.h>

@implementation RNGlobalManager
{
  bool hasListeners;
}

RCT_EXPORT_MODULE();

+ (id)allocWithZone:(NSZone *)zone {
  static RNGlobalManager *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}


- (NSArray<NSString *> *)supportedEvents
{
  return @[@"appCrashed", @"startObserving"];
}


-(void)startObserving {
  NSLog(@"RNGlobalManager startObserving");
  hasListeners = YES;
  [self sendEventWithName:@"startObserving"  body:@{@"name": @"startObserving"}];
}

-(void)stopObserving {
  NSLog(@"RNGlobalManager stopObserving");
  hasListeners = NO;
}

- (void)sendEvent:(NSString *)eventName {
   NSLog(@"RNGlobalManager sendGlobalEvent emitting event: %@", eventName);
  if (hasListeners) { 
    NSLog(@"RNGlobalManager hasListeners");
    [self sendEventWithName:@"appCrashed"  body:@{@"name": eventName}];
  }
}

@end

三、在app life cycle里调用这个自定义模块

修改AppDelegate.mm文件

+ #import "RNGlobalManager.h"

@implementation AppDelegate

+ RNGlobalManager *globalManager = NULL;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  RCTAppSetupPrepareApp(application);
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
+ globalManager = [RNGlobalManager allocWithZone: nil];

    ...
    return YES;
}

// 添加如下代码:
- (void)applicationWillTerminate:(UIApplication *)application {
    NSLog(@"========app killed==============");
    [globalManager sendEvent:@"appCrashed"];
}

image.png

四、JS端监听

修改App.js文件:

import { NativeModules, NativeEventEmitter } from "react-native";


const NativeEmitter = new NativeEventEmitter(NativeModules.RNGlobalManager)


  useEffect(() => {
    initTheme();
    console.log('___________________________')
    NativeEmitter.addListener("appCrashed", (reminder) => {
      console.log('reminder______________', reminder) // 打印信息1
      onDisplayNotification1()
    })
    NativeEmitter.addListener("startObserving", (reminder) => {
      console.log('reminder_____startObserving_________', reminder)  // 打印信息2
      onDisplayNotification2()
    })
    // return () => {
    //   console.log('sss')
    //   // subscription.remove();
    // }
  }, []);
  

实践结果

appCrashedstartObserving两个事件都能监听到(信息1和信息2都打印出来了),但是只有onDisplayNotification2通知发出了,即当打开app的时候会收到一个通知,但是onDisplayNotification1通知却没有收到,也就是说,当App被kill的时候事件JS监听到了,但是确没有执行后面的通知相关脚本了。

功能未实现,但是已经实现了用原生模块与JS通信问题,以及App被Kill事件监听问题。通知执行后续再战!

或许这篇文章可以给我帮助: How to run code when your app is terminated,择日再战,菇凉困了,睡觉~

相关链接