Взаимодействие Swift с JavaScript

Во все приложения для операционной системы 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, в котором описанные выше методики можно будет изучить наглядно. И может быть запишу процесс создания этого проекта на видео. Большое спасибо за внимание, надеюсь эти материалы оказались для вас полезны.

Добавить комментарий

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