
Что такое React Native

Что такое Native Modules

“Sometimes an app needs access to platform API, and React Native doesn't have a corresponding module yet. Maybe you want to reuse some existing Objective-C, Swift or C++ code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.”
Это именно наш случай, у нас в клиентском SDK voximplant есть множество штук, которые будут нормально работать только если написаны на достаточно низком уровне: видео/аудио кодеки, webrtc, srtp, ws и другие страшные слова. А разработчикам React Native приложений это все не очень интересно, они хотят иметь дело с понятным высокоуровневым javascript API, так как все их приложение это практиески сплошной javascript/jsx. Упаковка низкоуровневого кода в модуль React Native позволяет разработчикам фокусироваться на разработке приложений и не беспокоиться о магии под капотом.
Архитектура нативного модуля
Нативный модуль может содержать код на c/c++, на objective-c и на javascript. В низкоуровневый код мы вынесли сетевое взаимодействие с нашим облаком (c, c++, libwebrtc и небольшая кучка библиотек по мелочки) и отображение видео (objective-c). В высокоуровневый javascript код ушла обертка работы с облаком и два React виджета: один для предпросмотра собственного видео и второй для просмотра видео собеседника:

Технически разделение на низкоуровневый и высокоуровневый код происходит следующим образом: вы создаете objective-c класс, наследуемый от предоставляемого React’ом класса RCTBridgeModule. Используя максросы вида RCT_EXPORT_METHOD вы задаете точки взаимодействия с javascript кодом, в то время как в objective-c коде можно взаимодействовать с операционной системой, c/c++ библиотеками, создавать “родные” iOS виджеты и делать другие нужные и полезные вещи.
Готовый нативный модуль можно распространять разными способами, самый простой — это собрать исходники в виде .npm пакета и опубликовать его в репозитории. В таком случае для добавления модуля в свой проект достаточно сделать “npm install”, добавить .xcodeproj и собранную библиотеку (потому что пользователи ну явно не хотят собирать у себя libwebrtc с патчами — то еще удовольствие) и собрать свой проект.
Функционал

Использование модуля в React Native приложении
Инсталляция модуля выглядит достаточно просто, в директории проекта выполняем:
npm install react-native-voximplant@latest --save


В закладке «Build Settings» проверяем, что выбрано ‘All’ (а не ‘Basic’), находим Header Search Paths и удостовериваемся, что там есть $(SRCROOT)/../react-native/React и $(SRCROOT)/../../React и оба помечены как «recursive».
Вот и все, дальше пишем свое приложение, которое использует подключенный модуль:
немного кода
var VoxImplant = require(‘react-native-voximplant’);
// Adding SDK event listener
RCTDeviceEventEmitter.addListener(
'ConnectionSuccessful',
() => {
console.log('Connection successful');
}
);
...
componentDidMount: function() {
VoxImplant.SDK.connect();
VoxImplant.SDK.setCameraResolution(320,240);
},
…
makeCall: function() {
VoxImplant.SDK.createCall(number, settings_video, null, function(callId) {
currentCallId = callId;
VoxImplant.SDK.startCall(callId);
});
},
...
Чтобы упростить задачу ознакомления с модулем мы сделали демо-приложение, которое можно взять с github и собрать, следуя инструкциям на странице. В результате получается:

Заключение
Многие критикуют React Native, говоря о производительности javascript относительно “родного” кода. На самом же деле такие технологии позволяют совместить лучшее из обоих миров: высокоуровневый и лаконичный javascript используется для кода логики приложения, в то время как низкоуровневый код на c/c++/objective-c используется для библиотек и критичных по скорости участков логики. Такой подход позволяет равномерно размазывать сложность по частям приложения, избегая ее скапливания в одном месте — что часто ведет к переусложненному и неподдерживаемому коду.
Вопросы, комментарии, критика? Мы традиционно готовы общаться.