Native module to calculate poker stove for React Native
This is our first step in creating Native module for React Native apps. We have been developing React Native apps from past 4 years but we never had opportunity to create a native module. We have published this on npm here .
Task
We have been asked by our client if we can integrate a c++ library in one of their application, which is developed on React Native. The c++ library is published on git. We reviewed the library and defined the task required.
- Compiling C++ code in Objective C++
- Create ReactNative Module
- Execute and fetch result from Native module
Compiling C++ code in Objective C++
Our first target was to compile the c++ library in Objective C++. By default when you setup xcode project it have .m extension to the implementation’s file which doesn’t allow you to call c++ function. To do that we had to rename our implementation file to .mm extension. This tells xcode to allow mix of objective c++ and c++ code.
Second issue we had with headers. We had to provide correct header files of the above lib and boost lib. Boost generally available at /usr/loca/Cellar/boost/[version] on mac. Boost must be linked in Header and library search path.
Once we linked everything correctly, we were able to call c++ method from objective c++ code.
We needed to modify few things for example in Objective C++ we have NSString where in c++ its std::String. So we convert NSString to std::string and send parameters to c++ function. C++ function send us result in vector<string> which we converted back to Objective C++ code.
Create ReactNative Module
Next we needed to wrap this library in Native Module which then can be plugged in react native app.
We started with creating a native module from this library and we read the article by Roi. Now we had everything setup correctly. We modified RNPokerStoveLib.m to RNPokerStoveLib.mm and was able to talk to c++ lib.
Next we needed to setup podspec correctly so all the header files can be linked correctly. This was needed because the c++ library we are using have a defined folder structure which must be preserved when we install lib with pod install
It wasn’t easy as we did not find much information on how to preserve folder structure and header dir. After many test we find following code
`s.subspec "penum" do |ss|
ss.source_files = "pokerstove/penum/.{h,mm,m,cpp}"
ss.header_dir = "pokerstove/penum"
` end
After adding this block for rest of 2 header our pod spec was good. We have then publish it over npm to test if we can install this on react native project.
Execute and fetch result from Native module
Now we reached to our final task which was to install the npm module we published and then get the equity. Then we take the 3 golden step
$ npm install react-native-poker-stove-lib --save
$ react-native link react-native-poker-stove-lib
This build the library and we were able to call
we implemented in the RCT_EXPORT_METHOD
RNPokerStoveLib.mm
We successfully call the native method but the app looks hanged until c++ library run the code and provide us the result. So we needed to transfer the process to another thread. ReactNative provide us few approach to do that and we queue it to background process. This is useful so the application doesn’t look hanged. To do that we used following approach:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^callback}
We made above change in
and re-publish over module to npm and install it back in the app. Now The app does look hanged instead wait for result. Everything was good at the end. RNPokerStoveLib.mm
Articles we read:
https://medium.com/wix-engineering/creating-a-native-module-in-react-native-93bab0123e46
https://developer.apple.com/documentation/dispatch/dispatch_queue_priority_default