Доброго времени суток. В данной статье рассматривается пример реализации ReactJS-компонента в мобильном приложении, разработанном на движке Unity 2017.4 LTS. Польза владения таким инструментом обусловлена тем, что на момент написания настоящей статьи ReactJS является самой популярной библиотекой для создания веб-компонентов, и таких компонентов уже написано превеликое множество. Так почему бы этим не воспользоваться? Можно просто вставить готовый веб-компонент, который визуально будет неотличим от компонента интерфейса, реализованного на движке. Кроме того, даже если Вы не нашли нужное, то очевидно, что верстать и добавлять интерактив с помощью HTML+CSS+JS гораздо проще и приятнее, чем в Unity. Конечно, придется реализовать взаимодействие веб-компонента и приложения, о чем будет рассказано в статье.
Начнем с почвы. Для того, чтобы встроить React-компонент в мобильное приложение нам нужны React-компонент и мобильное приложение. Исходный код React-компонента Вы можете найти по этой ссылке, а проект Unity с уже встроенным WebView - по этой. WebView в данном контексте - это специальная обертка над встроенным в устройство браузером для вывода веб-страниц внутри приложения. В своих проектах мы используем две различных кроссплатформенных реализации WebView: платную и бесплатную. В примере, естественно, используется бесплатная.
Итак, с одной стороны имеется инструмент, позволяющий выводить Веб-страницы в приложении, реагировать на событие загрузки страницы при помощи одного callback-метода, принимать и обрабатывать сообщения от браузера при помощи другого, а также выполнять JavaScript-код. С другой - обыкновенный Веб-компонент, скрипт для которого написан на ReactJS. Цель - подружить обе стороны.
В общем случае нет необходимости как-то менять Веб-компонент для отображения через WebView, поскольку WebView использует встроенный в устройство браузер. При такой постановке страница выведется как есть. Нас такой расклад не устроил по двум причинам: во-первых, мы разрабатываем мобильное приложение, во-вторых, хотелось бы при инициализации React-компонента сразу передать ему нужные данные.
Первое накладывает свой отпечаток на файле HTML-разметки, в котором рендерится компонент. А именно, в содержимое тега
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#000000"> <meta name="description" content="React component for Unity-based mobile application"> <title>React Component</title> <script> // Пример передачи данных из приложения window.initialData = {}; // Данные будут переданы из Unity </script> </head>
Решение второй задачи, как можно видеть в предоставленном примере, заключается в том, что мы оборачиваем инициализацию ReactDOM.render() в функцию с параметром для данных, которую затем вызовем из приложения.
window.createAboutComponent = function (data) { ReactDOM.render(, document.getElementById('container')); };
С обыкновенными React-компонентами разобрались. Далее мы хотели улучшить компонент, добавив возможность передавать сообщения приложению. В предложенной реализации Webview это осуществляется при помощи объекта window.Unity, который содержит функцию call, обеспечивающую передачу строки в callback-метод C#. Для удобства лучше вынести взаимодействие компонента с Unity в отдельный скрипт.
function createAPIObject(w) { const APIObject = { //Закрывает Webview в приложении close: function() { if(window.Unity) window.Unity.call("close"); } }; APIObject.close = APIObject.close.bind(APIObject); return APIObject; } let api; //Инициализация объекта API (function Init(w) { if(!w.unityApi) { api = createAPIObject(w); w.unityApi = api; } else { api = w.unityApi; } })(window); export default { close: api.close, };
Теперь, добавляя в скрипт зависимость import unityApi from '../utils/unityApi';
разработчик получает доступ к функциям взаимодействия с Unity приложением.
Далее перейдем к нюансам в Unity. Есть две проблемы, причем, одна только с Android, другая со всеми, кроме Android. В Android, как известно, всё содержимое приложения есть Java-архив, из-за чего Unity приходится особым образом взаимодействовать с внутренними файлами, а именно при помощи класса www. Но, поскольку наш Веб-компонент поставляется как HTML файл с зависимостями, ссылки на нутро apk не работают. Проблему решает перенос таких файлов в persistentDataPath на время работы приложения. Пример реализации копирования файлов можно посмотреть в классе WebViewController, область Loading region.
В других системах, в том числе и в редакторе Unity, реализация WebView от Gree по каким-то причинам не инициализирует объект window.Unity. Исправим:
WebView.EvaluateJS(@" window.Unity = { call: function(msg) { var iframe = document.createElement('IFRAME'); iframe.setAttribute('src', 'unity:' + msg); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; } }; ");
Теперь callback Webview обрабатывает строку сообщения, переданную из браузера.
Осталось реализовать загрузку файла с Веб-компонентом и инициализировать его, передав нужные данные, что и сделано в методе WebViewController.LoadPage, который принимает в качестве параметров имя HTML-файла и строку JS кода для исполнения. В примере загружается страница характеристик товара и передается JSON-объект, представляющий данные для отображения. Важно отметить, что выполнение JS-кода необходимо осуществлять только после загрузки файла с компонентом и всех необходимых зависимостей. По этой причине переданная в обработчик WebView JS-строка сначала сохраняется в переменную и только по вызову callback-метода onLoad передается на исполнение.
На этом все. В заключение важно сказать, что созданные для мобильного приложения веб-компоненты обладают всеми преимуществами, которые предоставляет библиотека React, как, например, динамическая загрузка страницы и стилей. Богатая экосистема и компонентный подход позволяют многократно переиспользовать уже написанный код, не прибегая к существенным временным затратам. Кроме того, Facebook, как разработчик этой библиотеки, предоставляет отличные средства отладки React-компонентов в браузере, что в совокупе заметно ускоряет процесс создания конечного продукта в сравнении с другими известными JavaScript-фреймворками. По этим причинам React уже на протяжении более чем двух лет занимает позицию самой популярной библиотеки для Frontend-разработки и сохраняет такой статус к середине 2018 года.
Добавить комментарий