2017-05-31 7 views
2

Wie kann ein natives Modul zu einer internen JavaScript-Methode zurückrufen, dann die interne Methode verarbeiten, zum Beispiel Daten in JSON analysieren und dann ein Ereignis auslösen, das die native App empfängt?Wie schreibe ich ein natives "natives Modul" (Bridge), das gängigen JavaScript-Code wiederverwendet?

Für plattformübergreifende Brückenmodule möchte ich vermeiden, Code in beide Ziel C und Java zu duplizieren. Wenn es möglich ist, möchte ich plattformübergreifenden Brückenmodul-Code in JavaScript schreiben und für Android und iOS wiederverwenden.

Meine aktuelle Lösung:

Dies funktioniert.

  1. sendEventWithName mit dem "_processResponseInJavaScriptMethod"
  2. forwardEventWithName sendEventWithName auf die native App reagieren:

    Dies wird in zwei Anrufe zu sendEventWithName führen.

Frage:

Gibt es ein Konzept für die native Code-Daten zu verarbeiten synchron einen JS-Call, dann Ergebnisse senden sofort mit sendEventWithName?

Oder benötigt jeder native> JS-Aufruf eine asynchrone _bridge enqueueJSCall?

Datei: MyNativeModule.m

 
// Use forwardEventWithName to forward events 
// processed by common cross-platform JS to the react native app 
RCT_EXPORT_METHOD(forwardEventWithName:(NSString*)name 
        body:(NSString*)body) { 
    [self sendEventWithName:name body:body]; 
} 

// 1 - react native app calls sendQueryToBluetoothDevice 
// 2 - device calls commandResponse when response received 
RCT_EXPORT_METHOD(sendQueryToBluetoothDevice:(NSString*)command { 
    [_device sendCommand:command]; 
} 

// 1 - Receives XML response from external Bluetooth device 
// 2 - Sends XML to internal JS method for processing 
// 3 - Internal JS method uses forwardEventWithName 
//  to send event to react native app 
- (void) commandResponse:(NSString *) xml {  
    [self sendEventWithName:@"_processResponseInJavaScriptMethod" 
         body:@{@"xml": configuration}]; 

} 

Datei: index.js (native Modul)

 
// Parse xml in common JS code for both Android and iOS native modules 
emitter.addListener("_processResponseInJavaScriptMethod", (e) => { 
    const body = parseXml(e.xml); 

    // ?? Is there a way to send event directly using JS to the react native app ?? 

    // Hack - Call native method forwardEventWithName to sendEventWithName to react native app. 
    /// 
    // This makes two _bridge enqueueJSCall's 
    // 1 - One call to sendEventWithName "_myNativeModuleInternalMethod" 
    // 2 - Second call to sendEventWithName "myNativeModuleEvent 
    MyNativeModule.forwardEventWithName(
     'myNativeModuleEventResponseReceived', 
     JSON.stringify(body)); 
    } 
}) 

Antwort

1

nicht sicher, was Sie von Internal bridge module Java Script method bedeuten, aber JS-Code können die Daten übergeben zu nativen via Methoden, und native kann Daten zu JS über Callbacks oder Versprechen zurückgeben. Nativer Code kann auch Ereignisse an JS senden.

JS  --->  Native // Method calls 
Native --->  JS  // Callbacks, Promises, Events 

Siehe die native Modul Dokumentation für weitere Details: - https://facebook.github.io/react-native/docs/native-modules-ios.html - https://facebook.github.io/react-native/docs/native-modules-android.html

+0

Ich habe das native Modul arbeiten. Ich finde gerade, dass ich Code in Java und Objective C vervielfältige, die wiederverwendet werden könnten. Vielleicht ich AddListener in der index.js des bridge-Moduls und dann Callback von nativem Code empfangen, Daten verarbeiten, dann Ereignis ausstrahlen? Reactive-Native-Fetch-Blob erscheint, könnte es so etwas tun? https://github.com/wkh237/react-native-fetch-blob –

+0

Wie Sie es strukturieren, hängt von Ihnen ab. Sie haben Möglichkeiten für native, Informationen an JS und JS zu senden, um Informationen an native zu senden. – satya164

+0

Danke. Gibt es einen Ansatz für nativen Code, um Daten synchron mit einem JS-Aufruf zu verarbeiten, und Ergebnisse sofort mit sendEventWithName zu senden? –

1

Ich würde empfehlen, etwas zu lesen auf der Batched Brücke zu tun in der india React.

Native -> JS

Wesentlichen, was Sie tun können, ist ein Modul mit statischen Methoden auf der Seite JS definieren, die Sie dann mit dem BatchedBridge (registerCallableModule) registrieren - dies dann Sie diese direkt anrufen können Methode von der nativen Seite über RCTBridge().enqueueJSCall, wo Sie die moduleDotMethod, die Ihrem Modul bzw. Funktion entspricht; Sie würden auch eine eindeutige (oder inkrementelle) Kennung übergeben, die Sie später verwenden würden, um die Antwort auf jede Anforderung zuzuordnen.

JS -> Native

Als nächstes würden Sie eine native Module erstellen, die auf der JS-Seite aufgerufen werden würden Daten zurück an nativen zu schicken, die Antwortdaten und Identifikator übergeben, die Sie dann auf dem nativen behandeln würden Seite.

Ich habe an Projekten gearbeitet, bei denen der gesamte Service-Layer auf der JS-Seite steht und diesen Ansatz erfolgreich verwendet haben.

+0

Danke. Kannst du bitte "Meine aktuelle Lösung:" zur ursprünglichen Frage hinzufügen? Gibt es einen Ansatz für nativen Code, um Daten synchron mit einem JS-Aufruf zu verarbeiten, und Ergebnisse sofort mit sendEventWithName zu senden? Oder ist RCTBridge(). EnqueueJSCall der einzige Weg? –

+0

Nichts auf der Brücke ist synchron - der Synchronous-Aufruf ist am nächsten, wenn Sie 'constantsToExport' auf dem Modul verwenden. Diese Werte werden jedoch zur Laufzeit definiert und können nicht geändert werden. Sie können, wenn Sie den Event-Dispatcher verwenden möchten, aber dazu müssten Sie einen Listener auf der JS-Seite einrichten. – sooper

+0

Da nichts synchron ist, klingt es so, als wäre meine "Meine derzeitige Lösung" oben so gut wie möglich. Für zukünftige plattformübergreifende Wiederverwendbarkeit kann C++ in eine * .mm-Datei für iOS und eine in JNI für Android verpackte Datei eingebettet werden. Ich habe Qt 5.6 für iOS und Android benutzt, was eine C++ Umgebung ist, die ziemlich gut funktioniert hat. –

Verwandte Themen