Во все приложения для операционной системы iOS встроена поддержка веб-компонентов. Это нужно, преимущественно, для отображения каких-либо веб-страниц. Однако, для взаимодействия с веб-содержимым в приложениях — необходим некий «мост». От технологии Swift к технологии JavaScript. При разработке своего приложения для iOS я столкнулся с данной проблемой. В моем приложении существует WKWebView, который запускает фреймворк, написанный на JavaScript. Этот фреймворк в свою очередь берет данные для вычислений из базы данных SQLite нативного приложения, производит подсчеты, возвращает новые данные в Swift. Затем эти данные записывает обратно в базу данных. Чуть сложновато. Но речь не об этом.

К счастью компонент WKWebView оснащен таким «мостом» для взаимодействия между Swift и JavaScript. В данной статье разберем (с примером) его работу.

Ключевые компоненты

  • WKWebView — позволяет загрузить веб-контент по URL
  • WKScriptMessage — объект, который создается после выполнения метода postMessage()
  • WKUserContentController — менеджер отправки и получения JavaScript
  • WKScriptMessageHandler — протокол для доступа к методам WKScriptMessage
  • WKWebViewConfiguration — настройки, передаваемые в WKWebView

Краткий обзор

Диаграмма взаимодействия Swift с JavaScript

Диаграмма взаимодействия Swift с JavaScript

Представленная выше диаграмма отражает путь от и до web-view. Термин «doStuff» общий, пожалуйста, подключите ваше воображение для замены его поведением, которое вам нужно 😉

На приведенной выше диаграмме видно, что при правильно написанной программе взаимодействие начинается с компонента WebView. Первым делом запускается программа, написанная на языке Swift. Внутри программы срабатывают сценарии открытия компонента WebView. Данный компонент инициализирует загрузку в отдельном процессе веб-документа html. Затем html документ выполняет вложенный код JavaScript.

Вызов триггера postMessage

После того, как веб-документ загружен, весь код JavaScript обработан — начинается самое интересное. JavaScript вызывает триггер-метод postMessage в обработчике событий doStuffMessageHandler. ( ➡ Позже я покажу как добавить обработчик в коде Swift, который принимает имя doStuffMessageHandler’а. ) Тут важный момент 💡 Название обработчика событий (MessageHandler) может быть абсолютно любым. На ваше усмотрение. Например: turnOnMusic.postMessage(trackName). Важно запомнить, в коде Swift вам нужно будет обработать совпадение только с именем, которое идет до .postMessage(). Оно называется «messageName», а параметры, которые передаются в скобках postMessage(parameters) — «messageBody».

Теперь, давайте на примере проверим работоспособность нашей теории. Создадим новый пустой проект Xcode, и добавим в него пустой файл с именем index.html. Откроем этот файл в редакторе Xcode и пропишем следующее:

Чтобы этот код запустился, необходимо сначала загрузить веб-страницу в Swift:

В данном примере из JavaScript в Swift передаются два параметра, но вы можете добавлять столько параметров, сколько вам необходимо. JavaScript код можно добавлять несколькими способами. Можно встроить его непосредственно в html страницу, можно указать в html ссылку на .js файл со скриптом. Так же можно инжектировать скрипт с помощью WKUserScripts и метода addUserScript() в userContentController’е. Такого рода скрипты могут выполняться в момент, когда страница загружается или когда она завершила свою загрузку.

«Слушатели» метода postMessage() в iOs приложении

Для того, чтобы JavaScript мог обработать message handler, нужно чтобы была передана его конфигурация в WKWebView во время инициализации программы. Это делается с помощью вызова add() метода из userContentController свойства объекта WKWebViewConfiguration передающего имя handler’а. Класс, принимающий сообщения, также должен быть передан в метод add() как параметр. Рассмотрим пример:

Класс, передаваемый в add() метод должен соответствовать протоколу WKScriptMessageHandler. Это свойство разрешит нашему «целевому» классу делегировать методы, которые выполняются в следствии обработки определенного javascript handler’а. В следующем листинге мы расширяем наш класс WebViewController для удовлетворения протокола и добавляем метод didReceiveMessage для обработки событий:

Когда срабатывает postMessage триггер, делегирующий метод уведомляет приложение с помощью WKScriptMessage объекта. WKScriptMessage содержит «name», одинаковое с handler’ом, и «body», включающее в себя любые параметры или текст. Эти параметры посылаются из JavaScript в Swift. Для обработки сообщения мы должны поймать имя handler’а в Swift, и принять его параметры.

Обратная связь с web-view

Если приложение получило и обработало какие-то данные из JavaScript, почти наверняка оно должно вернуть результат этой обработки. Для обратного сообщения Swift с JavaScript существует метод evaluateJavascript. Этот метод принимает строку типа String, как параметр. Эта строка представляет собой некий код JavaScript или вызов JS функции. В качестве второго параметра идет блок, который срабатывает после отправки сообщения. Он также может вернуть ошибку, возникающую при отправки сообщения.

В коде выше мы передаем данные в формате JSON как строку.

Скрипт который мы «евалуируем», должен находиться на веб-странице, загруженной в web-view во время его запуска. Если это не так, вы можете посмотреть, как внедрить его с помощью метода addUserScript () в userContentController. Это финальный шаг сообщения приложения с веб-представлением.

В данной статье описана самая суть(ядро) взаимодействия Swift и JavaScript. Тут опущены некоторые подробности, отсутствие которых может сбить с толку новичков в Swift программировании. Дабы избежать замешательства, в ближайшее время я создам учебный проект в Xcode, в котором описанные выше методики можно будет изучить наглядно. И может быть запишу процесс создания этого проекта на видео. Большое спасибо за внимание, надеюсь эти материалы оказались для вас полезны.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Поделиться записью:

Комментарии:

Вы можете оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Используйте данные HTML тэги и атрибуты:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: