React-Nativeとオリジナルコード間のイベント転送

4568 ワード

iOSに詳しい学生は、controller間のイベントの伝達がいくつかあることを知っています.
  • エージェント
  • block
  • 通知
  • KVO

  • ではReact-Nativeと原生の間のイベント伝達にはどのようなものがあるのでしょうか.
    JSから原生へ
    JSからオリジナルコードへのイベント伝達はどのように行いますか?
    シーン1:まず1つのページがあって、ナビゲーションはオリジナルのUINavigationBarを使って、ページはJSコードを使って、今ページの中の1つのボタンをクリックして、ナビゲーションのタイトルを変えることを要求します.
    問題から分かるように、このページはネイティブとJSの2つの言語で作成されており、この問題を解決するには、JSコードのボタンをクリックすると、ネイティブコードを通知し、ナビゲーションタイトルを変更するという2つの言語を通信する必要があります.では、この2つの言語はどのように通信しますか?
  • は、オリジナルから導出されたModuleによってイベント通信を行う.すなわち、ボタンをクリックすると、このModuleが呼び出され、Moduleに後続のイベント伝達を処理させる.これにより,問題は原生コードに変換され,処理方式は多様な選択肢が得られる.もし、タイトルを修正した後、修正の結果を知りたいなら、原生にコールバックを渡して、修正の結果をJSに戻すこともできます.
  • JSから原生に通知し、まずこの方法が可能かどうかを考察します.react-nativeでは、まだこの方法を使ったことがないことを知り、この文章を読んだ皆さんの中で、この方法が役に立つとしたら、ご指導いただき、感謝に堪えません.
      /**
       * callback       
       */
      RCT_EXPORT_METHOD(handleEvent:(NSDictionary *)userInfo callback:(RCTResponseSenderBlock)callback) {
          NSLog(@"    =====> %@", userInfo);
          //       ,JS        JS     
          dispatch_async(dispatch_get_main_queue(), ^{
              UIApplication *application = [UIApplication sharedApplication];
              UINavigationController *navigation = (UINavigationController *)[application keyWindow].rootViewController;
              NSArray *keys = [userInfo isKindOfClass:[NSDictionary class]] ? userInfo.allKeys : nil;
              __block BOOL isSuccess = NO;
              if (keys && keys.count > 0) {
                  NSString *key = [keys firstObject];
                  [navigation.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                      if ([obj isKindOfClass:NSClassFromString(key)]) {
                          obj.title = [userInfo objectForKey:key];
                          *stop = YES;
                          isSuccess = YES;
                      }
                  }];
              }
              if (callback) {
                  callback(@[[NSString stringWithFormat:@"      %@", isSuccess ? @"  " : @"  "]]);
              }
          });
      }
    

  • 原生からJSへ
    上で述べたのは、JSコードからオリジナルコードへのイベント通信ですが、オリジナルからJSへの通信は何種類あるのでしょうか.
    シーン2:もしあなたのプロジェクトにリモートプッシュが統合されている場合、プッシュを受け取ったとき、JSコードでプッシュ情報を処理したいと思っています(厳粛な顔:なぜOCコードでプッシュを処理しないのですか?!).
    まず考えてみると、OCがOCにイベントを送信するには4つの方法がありますが、これらの方法はOCからJSに送信するのに適していますか?エージェント、blockの2つの方法は、イベント送信者と受信者が相互に参照することに依存しており、2つの異なる言語のインタラクションには適用されません.通知とKVOは受信者が観察者を登録するだけでよいが,残りの2つの方式が実行可能かどうか,幸いなことにreact-nativeはJS側でイベント購読者がイベントを受信することを提供し,通知に対してはこの方式が実行可能であるが,ある属性値の変化を観察するためにKVO方式は提供されない.したがって,最終的には通知を用いてイベント情報をJS側に送信する.
    react-nativeのコードライブラリでは、通知送信にModuleを提供して処理され、開発者はこのmoduleを継承するだけで、サブクラスは需要をさらに解読し、処理する必要があります.実は、ここではJSコードをアクティブに呼び出すことで、イベント情報をJS側に伝達します.コアメソッドは
    /**
     * Send an event that does not relate to a specific view, e.g. a navigation
     * or data update notification.
     */
    - (void)sendEventWithName:(NSString *)name body:(id)body;
    

    JSコードではまずサブスクライバを初期化する必要があります
    //         
    const subscription = new NativeEventEmitter(app.EventTower);
    

    リスニングを追加するには、必ず削除してください.
    //     
    _addListener = () => {
        this.remoteEmitter = subscription.addListener('remotePushDidReceivedEmitter', (userInfo) => {
            console.log('            ==>', userInfo);
            let count = this.state.count + 1;
            this.setState({
                count: count
            });
        });
    }
    
    //     
    _removeListener = () => {
        console.log('    ');
        //        
        // this.remoteEmitter && this.remoteEmitter.remove();
    
        // subscription.removeAllListeners("remotePushDidReceivedEmitter");
    
        subscription.removeListener('removeListener', this.remoteEmitter);
    }
    

    JSからJSへ
    JS=>OC,OC=>JS,OC=>OCといったところで、JS=>JSという差があります.一つの言語の内部の事件の伝達に対して、きっと実現方式は多種があることができて、私はJSの多くの使い方に対してもよく知らないで、ここでJSの中の“通知”のメカニズムだけを言います.
    シーンの使用:ページ階層が多い場合や、ページの関連付けが緊密でない場合に適用されます.
    _addListener = () => {
        //    JS   
        this.subscription = DeviceEventEmitter.addListener("TitleWillChangEmitter", (userInfo) => {
            console.log('      JS    ======>', userInfo);
            this._onPress(null, userInfo.title ? userInfo.title : "   ");
        });
     }
    
     _removeListener = () => {
        console.log('    ');
        this.subscription && this.subscription.remove();
    }
    

    イベント転送の使用
    周知のように、使用通知は性能を消耗しており、原生言語でもJSと原生言語の通信でも避けられないシーンがありますが、適量を使うことに注意してください.
    プロジェクトアドレス