{"id":46123,"date":"2017-03-09T17:22:13","date_gmt":"2017-03-09T11:52:13","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=46123"},"modified":"2018-02-26T12:19:46","modified_gmt":"2018-02-26T06:49:46","slug":"how-to-achieve-react-native-and-ios-bridging","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/how-to-achieve-react-native-and-ios-bridging\/","title":{"rendered":"How to Achieve React Native and iOS Bridging?"},"content":{"rendered":"<p>We love sharing our learning from the project. Recently, in one of our development projects, there was a need of bridging between iOS or Android and react-native. We were required to integrate the apple map with our application by writing the code in native iOS where the application would\u00a0interact with the operating system. Once we get the relevant data from apple map, we had to send that data to our JS.<\/p>\n<p>This is a great use case of bridging as you would be able to reuse of iOS or Android code in Javascript (react-native). In this blog, we have only covered the iOS and <a title=\"React Native Development Company\" href=\"http:\/\/www.tothenew.com\/react-native-development-services\">react native<\/a> part.<\/p>\n<p><strong>Before going through the examples we need to focus on some macros or libraries:<\/strong><\/p>\n<p><strong>1) RCTBridgeModule :<\/strong> RCTBridgeModule is a protocol. It provides an interface for registering a bridge module RCTBridgeModule<br \/>\n<code>@protocol RCTBridgeModule<\/code><\/p>\n<p><strong>2) RCT_EXPORT_MODULE(js_name):<\/strong>\u00a0Register your module with the bridge during class implementation. It has an argument js_name which is optional and it is used as the JS module name. In case if it is not defined, Objective-C class name will be defined as the JS module name.<\/p>\n<p><strong>3) RCT_EXPORT_METHOD(method)\\RCT_REMAP_METHOD(, method):<\/strong> Bridge modules can also define methods that are exported to JavaScript as <code>NativeModules.ModuleName.methodName<\/code>.<\/p>\n<p><strong>Example.,<\/strong><\/p>\n<p>[js]<br \/>\nRCT_EXPORT_METHOD(funcName:(NSString *)onlyString<br \/>\n                    secondName:(NSInteger)argInteger)<br \/>\n  { &#8230; }<br \/>\n[\/js]<\/p>\n<p>This is exposed to JavaScript as `NativeModules.ModuleName.funcName`.<\/p>\n<p>These methods can also return a Promise that are compatible with JS async functions.<\/p>\n<p><strong>Example.,<\/strong><\/p>\n<p>[js]<br \/>\n  RCT_EXPORT_METHOD(funcName:(NSString *)onlyString<br \/>\n                           resolver:(RCTPromiseResolveBlock)resolve<br \/>\n                            rejecter:(RCTPromiseRejectBlock)reject<br \/>\n   { &#8230; }<br \/>\n[\/js]<\/p>\n<p>This method has two parameters &#8211; resolver and a rejecter block. Calling this method from JS such as `NativeModules.ModuleName.funcName(aString)` will return promise which contains a resolver and rejecter.<\/p>\n<p><strong>Method definition of &#8216;RCTPromiseResolveBlock&#8217; and &#8216;RCTPromiseRejectBlock&#8217;.<\/strong><\/p>\n<p>[js]<br \/>\n     &#8211; typedef void (^RCTPromiseResolveBlock)(id result);<br \/>\n     &#8211; typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);<br \/>\n[\/js]<\/p>\n<p><strong>4) RCT_REMAP_METHOD(js_name, method)\\RCT_EXTERN_REMAP_METHOD(js_name, method) :<\/strong> It is similar to RCT_EXPORT_METHOD, but it sets the method name which is exported to the JS.<\/p>\n<p><strong>Example usage:<\/strong><\/p>\n<p>[js]<br \/>\n  RCT_REMAP_METHOD(getThing,<br \/>\n                   resolver: (RCTPromiseResolveBlock)resolve<br \/>\n                   rejecter:(RCTPromiseRejectBlock)reject)<br \/>\n  { &#8230; }<br \/>\n[\/js]<\/p>\n<p>This method is available in JS as <code>NativeModules.GetData.getThing()<\/code>.<\/p>\n<p><strong>Outlined below are some example to explain this<\/strong><\/p>\n<p><strong>Example 1<\/strong><\/p>\n<p>This example contains a text and a button and on clicking the button, the text value changes. The changed text is received from the native iOS code.<\/p>\n<p>In the example, we have a module &#8216;GetData&#8217; and a method &#8216;getThing()&#8217; that returns a promise.<\/p>\n<p>Create two files &#8216;GetData.h&#8217; and &#8216;GetData.m&#8217; in ios directory. While\u00a0<code>'.h'<\/code> file declares the interface,\u00a0<code>'.m'<\/code> file implements the interface.<\/p>\n<p>[js]<br \/>\n\/\/ GetData.h file<\/p>\n<p>#import &lt;Foundation\/Foundation.h&gt;<br \/>\n#import &lt;React\/RCTBridgeModule.h&gt;<br \/>\n@interface GetData : NSObject &lt;RCTBridgeModule&gt;<br \/>\n@end<br \/>\n[\/js]<\/p>\n<p>&#8216;GetData&#8217; is the module that is available in &#8216;NativeModules&#8217; of react native. RCTBridgeModule is the protocol which is used to register module &#8216;GetData&#8217; for bridging.<\/p>\n<p>[js]<br \/>\n\/\/ GetData.m file<\/p>\n<p>#import &quot;GetData.h&quot;<br \/>\n@implementation GetData<br \/>\nRCT_EXPORT_MODULE();<br \/>\nRCT_REMAP_METHOD(getThing,<br \/>\n                 resolver: (RCTPromiseResolveBlock)resolve<br \/>\n                 rejecter: (RCTPromiseRejectBlock)reject)<br \/>\n{<br \/>\n  NSString *thingToReturn = @&quot;Hello World!&quot;;<br \/>\n  resolve(thingToReturn);<br \/>\n}<br \/>\n@end<\/p>\n<p>[\/js]<\/p>\n<p>In the above code, a method <code>getThing()<\/code> is defined which returns a promise.<\/p>\n<p>&#8211; NSString *thingToReturn = @&#8221;Hello World!&#8221;;<br \/>\nThis line of code declares a string &#8216;thingToReturn&#8217; which contains the value &#8220;Hello World!&#8221;.<\/p>\n<p>&#8211; resolve(thingToReturn);<br \/>\nThis line returns a resolver in JS code.<\/p>\n<p>Furthermore, to use &#8216;GetData&#8217; native module from JavaScript, you require NativeModules from &#8216;react-native&#8217; and from NativeModules we get native module &#8216;GetData&#8217; and use in the Js like &#8216;NativeModules.GetData&#8217;.<\/p>\n<p>[js]<br \/>\nimport {NativeModules} from &#8216;react-native&#8217;<br \/>\n[\/js]<\/p>\n<p>[js]<br \/>\nexport default class IOS_ReactNative_communication extends Component {<\/p>\n<p>constructor(props) {<br \/>\n    super(props);<br \/>\n    this.state = {<br \/>\n       text: &#8216;Bye Bye World&#8217;<br \/>\n  }<br \/>\n}<\/p>\n<p>render() {<br \/>\n  return (<br \/>\n   &lt;View style={styles.container}&gt;<br \/>\n     &lt;Text style={styles.welcome}&gt;{this.state.text}&lt;\/Text&gt;<br \/>\n     &lt;TouchableOpacity&gt;<br \/>\n       &lt;View style={styles.button}&gt;<br \/>\n         &lt;Text style={styles.buttonText}<br \/>\n         onPress={() =&gt; { this.buttonClick()}}&gt;Change Text.&lt;\/Text&gt;<br \/>\n       &lt;\/View&gt;<br \/>\n     &lt;\/TouchableOpacity&gt;<br \/>\n   &lt;\/View&gt;<br \/>\n  );<br \/>\n }<br \/>\n}<br \/>\n[\/js]<\/p>\n<p>[js]<br \/>\nbuttonClick = async () =&gt; {<br \/>\n  let newString =  await NativeModules.GetData.getThing();<br \/>\n  this.setState({text: newString})<br \/>\n}<br \/>\n[\/js]<\/p>\n<p>As soon as the button clicks, buttonClick function is called and from that buttonClick function we can call the native method &#8216;getThing()&#8217; similar to &#8216;NativeModules.GetData.getThing()&#8217; and as this is a promise we can use &#8216;async&#8217; and &#8216;await&#8217;.<\/p>\n<p><strong>Output : <\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-46182\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.41.09-AM-164x300.png\" alt=\"Screen Shot 2017-02-17 at 10.41.09 AM\" width=\"164\" height=\"300\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.41.09-AM-164x300.png 164w, \/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.41.09-AM.png 378w\" sizes=\"(max-width: 164px) 100vw, 164px\" \/><\/p>\n<p><strong>After Button Clicking<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-46183\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.42.15-AM-162x300.png\" alt=\"Screen Shot 2017-02-17 at 10.42.15 AM\" width=\"162\" height=\"300\" \/><\/p>\n<p><strong>Example 2<\/strong><\/p>\n<p>This example explains a callback in iOS native that can be used in JS.<\/p>\n<p>It contains two files with extensions <code>.h<\/code> and <code>.m<\/code>. The content of the <code>.h<\/code> file remains same. In <code>.m<\/code> file we declare a method <code>replaceString<\/code> which is used to replace the &#8216;First&#8217; text with &#8216;Second&#8217; in a string &#8216;input&#8217; received from JS.<\/p>\n<p>[js]<br \/>\n\/\/ GetData.m file<\/p>\n<p>#import &quot;GetData.h&quot;<br \/>\n@implementation GetData<br \/>\nRCT_EXPORT_MODULE();<\/p>\n<p>RCT_EXPORT_METHOD(replaceString:(NSString *)input callback:(RCTResponseSenderBlock)callback)<br \/>\n{<br \/>\n  callback(@[[input stringByReplacingOccurrencesOfString:@&quot;First&quot; withString:@&quot;Second&quot;]]);<br \/>\n}<br \/>\n@end<br \/>\n[\/js]<\/p>\n<p>[js]<br \/>\n\/\/index.io.js<\/p>\n<p>import React, { Component } from &#8216;react&#8217;;<br \/>\nimport {<br \/>\n  AppRegistry,<br \/>\n  StyleSheet,<br \/>\n  Text,<br \/>\n  View,<br \/>\n  NativeModules,<br \/>\n  TouchableOpacity<br \/>\n} from &#8216;react-native&#8217;;<\/p>\n<p>export default class IOS_ReactNative_communication extends Component {<br \/>\n    constructor(props) {<br \/>\n        super(props);<br \/>\n        this.state = {<br \/>\n            text: &#8216;First Example&#8217;<br \/>\n        }<br \/>\n    }<\/p>\n<p>    buttonClick = () =&gt; {<br \/>\n        NativeModules.GetData.replaceString(this.state.text, (text) =&gt; {<br \/>\n            this.setState({text});<br \/>\n        });<br \/>\n    }<\/p>\n<p>    render() {<br \/>\n        return (<br \/>\n            &lt;View style={styles.container}&gt;<br \/>\n              &lt;Text style={styles.welcome}&gt;{this.state.text}&lt;\/Text&gt;<br \/>\n              &lt;TouchableOpacity&gt;<br \/>\n                &lt;View style={styles.button}&gt;<br \/>\n                    &lt;Text style={styles.buttonText}<br \/>\n                          onPress={() =&gt; { this.buttonClick()}}&gt;Change Text.&lt;\/Text&gt;<br \/>\n                &lt;\/View&gt;<br \/>\n              &lt;\/TouchableOpacity&gt;<br \/>\n            &lt;\/View&gt;<br \/>\n        );<br \/>\n    }<br \/>\n}<\/p>\n<p>const styles = StyleSheet.create({<br \/>\n    container: {<br \/>\n        flex: 1,<br \/>\n        justifyContent: &#8216;center&#8217;,<br \/>\n        alignItems: &#8216;center&#8217;,<br \/>\n        backgroundColor: &#8216;#F5FCFF&#8217;,<br \/>\n    },<br \/>\n    welcome: {<br \/>\n        fontSize: 20,<br \/>\n        textAlign: &#8216;center&#8217;,<br \/>\n        margin: 10,<br \/>\n    },<br \/>\n    instructions: {<br \/>\n        textAlign: &#8216;center&#8217;,<br \/>\n        color: &#8216;#333333&#8217;,<br \/>\n        marginBottom: 5,<br \/>\n    },<br \/>\n    button: {<br \/>\n        backgroundColor: &#8216;#ff8000&#8217;,<br \/>\n        borderRadius: 4,<br \/>\n        padding:10<br \/>\n    },<br \/>\n    buttonText : {<br \/>\n        color : &#8216;#fff&#8217;,<br \/>\n        textAlign:&#8217;center&#8217;,<br \/>\n        fontWeight: &#8216;bold&#8217;<br \/>\n    },<br \/>\n});<\/p>\n<p>AppRegistry.registerComponent(&#8216;IOS_ReactNative_communication&#8217;, () =&gt; IOS_ReactNative_communication);<\/p>\n<p>[\/js]<\/p>\n<p><strong>The NativeModules contains the &#8216;GetData&#8217; module which has &#8216;replaceString&#8217; method.<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-46194\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-11.33.19-AM-300x182.png\" alt=\"Screen Shot 2017-02-17 at 11.33.19 AM\" width=\"300\" height=\"182\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-11.33.19-AM-300x182.png 300w, \/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-11.33.19-AM-1024x623.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-11.33.19-AM-624x380.png 624w, \/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-11.33.19-AM.png 1080w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><strong>Output : <\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-46184\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.59.02-AM-163x300.png\" alt=\"Screen Shot 2017-02-17 at 10.59.02 AM\" width=\"163\" height=\"300\" \/><\/p>\n<p><strong>After clicking on button<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-46185\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.59.14-AM-163x300.png\" alt=\"Screen Shot 2017-02-17 at 10.59.14 AM\" width=\"163\" height=\"300\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.59.14-AM-163x300.png 163w, \/blog\/wp-ttn-blog\/uploads\/2017\/02\/Screen-Shot-2017-02-17-at-10.59.14-AM.png 375w\" sizes=\"(max-width: 163px) 100vw, 163px\" \/><\/p>\n<p>It is also possible to write the same iOS native code in swift if you are familiar with swift.<br \/>\nBridging can also be achieved in Android and react-native in the same way as we have achieved in this blog.<\/p>\n<p>You can find the code snippets of above examples\u00a0<a href=\"https:\/\/github.com\/priya1091992\/iOS_ReactNative_Communication\">here<\/a>\u00a0 Hope these snippets and information provided in the blog is helpful.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We love sharing our learning from the project. Recently, in one of our development projects, there was a need of bridging between iOS or Android and react-native. We were required to integrate the apple map with our application by writing the code in native iOS where the application would\u00a0interact with the operating system. Once we [&hellip;]<\/p>\n","protected":false},"author":1027,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":25},"categories":[518,3429,1772],"tags":[4845,3259,4848,4424,4851,3505,4857],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/46123"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1027"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=46123"}],"version-history":[{"count":1,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/46123\/revisions"}],"predecessor-version":[{"id":52758,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/46123\/revisions\/52758"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=46123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=46123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=46123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}