Разработка
Как запустить нативный код из WKWebView
Знаете ли вы, что iOS-приложениt Википедия имеет открытый исходный код и он доступен для всех, кому интересно узнать о его внутреннем устройстве?
Несколько недель назад я решил потратить 2 часа на изучение этой кодовой базы, потому что у меня было чувство, что я могу узнать что-то ценное.
Я рад сообщить, что действительно узнал кое-что очень интересное, и именно этим я хочу поделиться с вами в этой статье.
Когда вы изучаете такую огромную кодовую базу, вам нужно сосредоточиться на чем-то конкретном, иначе вы просто пройдете по поверхности.
Поэтому я решил сосредоточиться на одном из основных экранов приложения: экране, отображающем содержимое статьи Википедии.
Как видите, этот экран позволяет пользователю прочитать все содержимое статьи и взаимодействовать с ним:
- нажатие на ссылку на другую статью вызывает навигацию
- нажатие на изображение модально отображает новый экран
- при нажатии на сноску отображается ее подробное описание и обновляется панель навигации
На первый взгляд мне показалось, что этот экран был реализован либо с помощью одного UITextView
, либо с помощью UICollectionView
, содержащего несколько UILabel
.
Но когда я воспользовался инструментом отладки Xcode для захвата иерархии представлений, я был очень удивлен, увидев, что на самом деле она была реализована с помощью WKWebView
!
Я iOS-разработчик, который твердо верит в нативные приложения, и как вы можете догадаться, конечно, я не самый большой поклонник веб-представлений.
Поэтому видеть, как веб-представление используется для реализации основной функции популярного приложения, было довольно неожиданно и тревожно!
Но если подумать, то этот выбор имеет большой смысл: Википедия — это, прежде всего, веб-сайт, и его содержимое было создано для отображения с помощью HTML и CSS.
Учитывая это, приложению Wikipedia действительно имеет смысл использовать веб-представление для отображения своего контента, а не тратить драгоценное время и энергию на то, чтобы воспроизвести точно такой же вид и ощущение с помощью родных компонентов iOS.
Однако это не объясняет одного: каким образом это веб-представление способно вызывать нативную навигацию в ответ на взаимодействие с пользователем?
На самом деле это реализовано с помощью очень мощного, но не очень известного API, представленного Apple в iOS 8 и называемого WKScriptMessageHandler
.
Этот API позволяет предоставить JavaScript-коду, выполняющемуся внутри веб-представления, специальную функцию, которая, будучи вызванной, запустит нативный код в приложении, в которое встроено это веб-представление.
Вот как это работает:
1. Приложение создает бридж для получения сообщений от веб-представления
2. Пользователь нажимает на ссылку в web view
3. JavaScript-код в веб-представлении вызывает функцию webkit.messageHandlers.bridge.postMessage(message)
4. Веб-представление пересылает сообщение своему контроллеру userContentController
5. Контроллер userContentController
анализирует содержимое сообщения
6. Выполняется нативный код для выполнения действия, соответствующего тому, как пользователь взаимодействовал с приложением
А вот как нажатие на ссылку в веб-представлении приводит к появлению нового View Controller в стеке навигации 🙌.
Чтобы быть на 100% корректным, также выполняется некоторый дополнительный код, чтобы предотвратить загрузку новой страницы самим веб-представлением:
Видите ли, я определенно не врал, когда утверждал, что вы можете научиться некоторым действительно крутым трюкам, просто потратив пару часов на изучение открытой базы кода популярного приложения для iOS!
Так что если у вас есть время, я бы очень рекомендовал вам попробовать и начать изучать открытую базу кода: Я уверен, что по пути вы узнаете что-то полезное.
Подробные списки приложений для iOS с открытым исходным кодом вы можете найти здесь, здесь или здесь.