2017-05-31 4 views
2

Comment un module natif peut-il rappeler une méthode de pont interne JavaScript, puis effectuer un traitement dans la méthode interne, par exemple analyser des données dans JSON, puis déclencher un événement que l'application native réagit?Comment écrire réagissent natif "module natif" (pont) qui réutilise le code JavaScript commun?

Pour les modules de pont multiplateformes, je souhaite éviter la duplication de code dans à la fois Objective C et Java. Lorsque cela est possible, je veux écrire du code de module de pont multiplateforme en JavaScript et réutiliser pour Android et iOS.

Ma solution actuelle:

Cela fonctionne.

Cela se traduira par deux appels à sendEventWithName:

  1. sendEventWithName avec le "_processResponseInJavaScriptMethod"
  2. forwardEventWithName à sendEventWithName à réagir application native.

Question:

Y at-il une approche pour le code natif pour traiter les données en utilisant un appel synchrone JS, puis envoyer les résultats immédiatement sendEventWithName?

Ou tout appel natif> JS nécessite-t-il un code asynchrone _bridge enqueueJSCall?

fichier: 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}]; 

} 

fichier: index.js (module natif)

 
// 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)); 
    } 
}) 

Répondre

1

Je ne sais pas ce que vous entendez par Internal bridge module Java Script method, mais le code JS peut transmettre des données à natif via des méthodes, et natif peut renvoyer des données à JS via des rappels ou des promesses. Le code natif peut également envoyer des événements à JS.

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

Consulte la documentation du module natif pour plus de détails: - https://facebook.github.io/react-native/docs/native-modules-ios.html - https://facebook.github.io/react-native/docs/native-modules-android.html

+0

J'ai le module natif qui fonctionne. Je me trouve juste en train de dupliquer du code en Java et Objective C qui pourrait être réutilisé. Peut-être que j'ajouteListener dans le fichier index.js du module beridge et que je reçois le callback du code natif, traite les données, puis émet un évènement? reac-native-fetch-blob semble-t-il faire quelque chose comme ça? https://github.com/wkh237/react-native-fetch-blob –

+0

Comment vous structurez cela dépend de vous. Vous avez des moyens pour natif d'envoyer des informations à JS et JS pour envoyer des informations à natif. – satya164

+0

Merci. Existe-t-il une approche pour le code natif pour traiter les données de manière synchrone à l'aide d'un appel JS, puis envoyer les résultats immédiatement avec sendEventWithName? –

1

Je recommande de faire un peu de lecture sur le pont dans React autochtones lots #.

Native -> JS

Essentiellement ce que vous pouvez faire est de définir un module avec des méthodes statiques sur le côté JS qui alors vous inscrire auprès du BatchedBridge (registerCallableModule) - cela, alors vous permet d'appeler directement cette méthode du côté natif via RCTBridge().enqueueJSCall, où vous devez fournir le moduleDotMethod qui correspond à votre module et la fonction respectivement; vous devez également transmettre un identifiant unique (ou incrémental) que vous utiliserez ultérieurement pour mapper la réponse à chaque requête.

JS -> Natif

Ensuite, vous créerez un module natif qui serait appelé sur le côté JS pour envoyer des données à natif, en passant les données de réponse et identifiant qui vous alors gérer le natif côté.

J'ai travaillé sur des projets où la couche de service entière est du côté JS et que j'ai utilisé cette approche avec succès.

+0

Merci. Pouvez-vous s'il vous plaît commenter sur "Ma solution actuelle:" ajouté à la question d'origine? Existe-t-il une approche pour le code natif pour traiter les données de manière synchrone à l'aide d'un appel JS, puis envoyer les résultats immédiatement avec sendEventWithName? Ou est RCTBridge(). EnqueueJSCall le seul moyen? –

+0

Rien sur le pont n'est synchrone - le plus proche des appels synchrones est d'utiliser 'constantsToExport' sur le module, mais ces valeurs sont définies lors de l'exécution et ne peuvent pas être modifiées. Vous pouvez si vous voulez utiliser le répartiteur d'événements, mais cela vous obligerait à configurer un écouteur sur le côté JS. – sooper

+0

Puisque rien n'est synchrone, il semble que ma «solution actuelle:» affichée ci-dessus est à peu près aussi bonne que possible. Pour la réutilisabilité multi-plateforme future, je peux envisager C++ enveloppé dans un fichier * .mm pour iOS et un enveloppé dans JNI pour Android. J'avais utilisé Qt 5.6 pour iOS et Android qui est l'environnement C++ qui a plutôt bien fonctionné. –