Как превратить ваш веб-сайт в мобильное приложение с помощью 7 строк JSON

1656654990 kak prevratit vash veb sajt v mobilnoe prilozhenie s pomoshhyu 7

от Этана

Новый подход для смешивания веб-движка с родными программами

Что если бы я тебе сказал 7 строк JSON выше, окрашены в оранжевый цвет или все, что вам нужно, чтобы превратить веб-сайт в мобильное приложение? Нет необходимости переписывать свой веб-сайт с помощью какого-либо фреймворка API, чтобы он работал как мобильное приложение. Просто перенесите существующий веб-сайт как есть и объедините его с родной программой с помощью простой ссылки на URL.

А что, если, просто немного настроив разметку JSON, вы сможете получить доступ ко всем нативным API, нативным компонентам пользовательского интерфейса, а также нативным переходам представления из коробки?

Вот как выглядит минимальный пример в действии:

1kjzo4uXso3Yk08RYYUUYGK6HXrlCs42aXqG

Обратите внимание, как я встроил веб-страницу github.com, но остальные макеты — это все компоненты собственного пользовательского интерфейса, такие как заголовок навигации и нижняя панель вкладок. И переход происходит автоматически без необходимости переписывать сайт с помощью API.

Прежде чем я объясню, как вы можете спросить: «Это круто, но можете ли вы сделать что-то значимое, кроме простого отображения веб-страницы в родном фрейме программы?»

Прекрасный вопрос, потому что это главная тема этого сообщения. Все, что вам нужно сделать, это создать бесшовный Двусторонний канал связи между просмотром и программойпоэтому родительская программа может запускать любые функции JavaScript в просмотре, а просмотр может выходить за пределы, чтобы вызвать собственные API.

Вот один из следующих примеров:

8AvgutqafADVJW2WYgH3o0kBVDZvVuUIoU6C

Обратите внимание, что это представление содержит:

  1. Встроенный заголовок навигации со встроенной функцией перехода
  2. Веб-просмотр, в котором встроена веб-приложение для создания QR-кода
  3. Нативный компонент ввода чата внизу

Всё это можно описать, просто настроив некоторые атрибуты разметки JSON, которые мы видели выше.

Напоследок заметьте, что QR-код меняется, когда вы вводите что-то в чате. Ввод чата запускает функцию JavaScript в веб-приложении QR-кода, которая повторно генерирует изображение.

Никакая структура разработки приложений не пыталась фундаментально решить эту проблему. «Плохая интеграция веб-просмотра в нативные программы» потому что все они сосредоточены на выборе 100% нативного или 100% HTML5.

Каждый раз, когда вы слышите, как кто-то говорит о будущем мобильных приложений, вы, вероятно, услышите, как они говорят об этом «Победит ли подход HTML5? Или будет родным?

Никто из них не видит native и html как нечто, что могло бы сосуществовать и, кроме того, создавать синергию и добиваться того, что невозможно иначе.

В этой статье я объясню:

  • Почему сочетание веб-движка и нативных компонентов часто является хорошей идеей.
  • Почему безупречная интеграция HTML и Native непроста, и как я это реализовал.
  • Самое важное, как Вы можете использовать его, чтобы мгновенно создать собственную программу.

Зачем использовать HTML в нативной программе?

Прежде чем идти дальше, давайте сначала обсудим, хорошая ли это идея, и когда вы можете применить этот подход. Вот несколько возможных случаев использования:

1. Используйте собственные веб-функции

Некоторые части вашего приложения можно лучше реализовать с помощью веб-механизма. Например, Websocket – это веб-функция, разработанная для веб-среды. В этом случае имеет смысл использовать встроенный веб-движок (WKWebView для iOS и WebView для Android) вместо установления посторонней библиотеки, по существу «эмулирует» Websocket.

Не нужно устанавливать дополнительный код, чтобы сделать то, что вы можете делать бесплатно, что подводит нас к следующему пункту.

2. Избегайте большого двоичного размера

Возможно, вы захотите быстро включить функции, иначе требующие огромной сторонней библиотеки.

Например, чтобы интегрировать генератор QR-кода нативно, вам нужно будет установить какую-то стороннюю библиотеку, которая увеличит двоичный размер. Но если вы используете механизм просмотра и библиотеку JavaScript через простой <script src>, вы получаете все это бесплатно, и вам не нужно устанавливать какие-либо собственные библиотеки сторонних разработчиков.

3. Надежной мобильной библиотеки не существует

Для некоторых передовых технологий нет надежной и стабильной мобильной реализации.

К счастью, большинство этих технологий имеют веб-реализацию, поэтому самый эффективный способ их интегрировать — это использовать библиотеку JavaScript.

4. Создайте частично нативные, частично веб-приложения

Многие новые разработчики, которые хотят перенести свой веб-сайт в приложение для мобильных устройств, отчаиваются или ошеломлены, когда обнаруживают, что некоторые из существующих функций веб-сайта слишком сложны, чтобы быстро переписать их с нуля для каждой мобильной платформы.

Например, у вас может быть одна веб-страница, слишком сложная для немедленного преобразования в мобильное приложение, но остальной веб-сайт можно легко преобразовать.

В этом случае было бы здорово, если бы существовал способ создать большую часть программы нативно, но для этой конкретной сложной веб-страницы как-то легко интегрировать ее в программу как HTML.

Как это работает?

А. Жазонетт

Jasonette – это подход с открытым исходным кодом, основанный на разметке, для создания кроссплатформенных нативных программ.

Это как веб-браузер, но вместо того, чтобы интерпретировать разметку HTML в веб-страницах, он интерпретирует разметку JSON в родных приложениях на iOS и Android.

Подобно тому, как все веб-браузеры имеют совершенно одинаковый код, но могут предоставлять вам разнообразные веб-приложения, интерпретируя разную разметку HTML по требованию, все программы Jasonette имеют совершенно одинаковый двоичный код, и он интерпретирует различную разметку JSON по требованию, чтобы создать вашу программу. Разработчикам никогда не нужно прикасаться к коду. Вы создаете программы, создавая разметку, которая переводится на нативную программу в режиме реального времени.

Вы можете узнать больше о Jasonette здесь.

Хотя Jasonette по своей сути посвящена созданию нативных приложений, эта конкретная статья посвящена интеграции HTML в основной нативный движок, так что давайте поговорим об этом.

B. Веб-контейнер Jasonette

Собственные программы – это отлично, но иногда нам нужно использовать веб-функции.

Но интеграция просмотров в нативную программу является сложным делом. Безупречная интеграция требует:

  1. Веб-просмотр должен быть интегрирован как часть нативного макета: Веб-просмотр должен сливаться с программой как часть собственного макета и обрабатывается так же, как и любые другие компоненты пользовательского интерфейса. Иначе он будет казаться неуклюжим, и будет выглядеть точно так же, как это – сайт.
  2. Родительская программа может управлять дочерним веб-контейнером: Родительская программа должна иметь возможность свободно контролировать дочерний просмотр.
  3. Дочерний веб-контейнер может инициировать события в родительской программе: Дочерняя программа должна иметь возможность запускать события родительского приложения для запуска собственных API.

Это очень много работы, поэтому я сначала работал только над первой частью головоломки. просто встраивая веб-контейнер в нативный макет – и выпустил его как версию 1:

Веб-контейнер JSON
HTML внутри JSON превращается в собственные компоненты программыjasonette.com

Это уже было достаточно полезно, но оно все еще имело ограничение неинтерактивности..

Родительская программа не могла контролировать дочерний веб-контейнер, а дочерняя программа не могла сообщить родителям о каких-либо событиях.сохраняя веб-контейнер полностью изолированным от внешнего мира.

C. Jasonette Web Container 2.0: Сделайте его интерактивным

После выпуска версии 1 я поэкспериментировал со второй частью головоломки. добавление интерактивности в веб-контейнер.

В следующем разделе объясняется решение, добавленное, чтобы сделать статические веб-контейнеры ранее интерактивными, сделав их значительно более мощными.

Реализация: интерактивный веб-контейнер

1. Загрузить по URL-адресу

проблема

Ранее в версии 1, чтобы использовать веб-контейнер в качестве компонента просмотра фона, вам нужно было сначала установить $jason.body.background.type к "html" а затем жестко закодируйте текст HTML под $jason.body.background.text такой атрибут:

{  "$jason": {    "head": {      ...    },    "body": {      "background": {        "type": "html",        "text": "<html><body><h1>Hello World</h1></body></html>"      }    }  }}

Естественно, люди хотели иметь возможность создать экземпляр контейнера, используя просто веб-URL, вместо того чтобы жестко кодировать весь текст HTML в одной строке.

Решение

Веб-контейнер 2.0 добавил url атрибут. Вы можете вставить локальный file:// Такой HTML (он загружается из локального файла HTML, который вы отправляете вместе с программой):

{  "$jason": {    "head": {      ...    },    "body": {      "background": {        "type": "html",        "url": "file://index.html"      }    }  }}

Или встроить пульт http[s]:// Такой URL-адрес (он загружается из удаленного HTML):

{  "$jason": {    "head": {      ...    },    "body": {      "background": {        "type": "html",        "url": "      }    }  }}

2. Родительская программа <=> Web Container Communiкатион

проблема

Ранее веб-контейнеры были только для отображения содержимого, а не интерактивными. Это означало Ни одно из следующих не было возможным:

  1. Jasonette => Web Container: вызов функций JavaScript внутри веб-контейнера из Jasonette.
  2. Веб-контейнер => Jasonette: вызов родного API из кода веб-контейнера.

Все, что вы могли сделать, это отобразить веб-контейнер. Это было похоже на то, как вы вставляете iframe в веб-страницу, но главная веб-страница не имела доступа к тому, что было внутри iframe.

Решение

Суть Jasonette заключается в разработке стандартного языка разметки для описания кроссплатформенных мобильных приложений. В этом случае нам нужен был язык разметки, который мог бы исчерпывающе описать связь между родительской программой и дочерним веб-контейнером.

Чтобы достичь этого, я придумал a JSON-RPC канал связи между родительским приложением и дочерним веб-контейнером. Поскольку все в Jasonette выражается в объектах JSON, было целесообразно использовать стандартный формат JSON-RPC в качестве протокола связи.

dISqZspArHgei6hasHQ89nw7g1GrWSsyPG8s

Чтобы сделать вызов функции JavaScript в веб-контейнере, мы объявляем вызов действия $agent.request:

{  "type": "$agent.request",  "options": {    "id": "$webcontainer",    "method": "login",    "params": ["username", "password"]  }}

$agent.request это родной API, запускающий запрос JSON-RPC в веб-контейнер. Чтобы использовать его, мы должны передать an options объект как его параметр.

The options object — это фактический запрос JSON-RPC, который будет отправлен в веб-контейнер. Давайте рассмотрим значение каждого атрибута:

Полная разметка будет выглядеть примерно так:

{  "$jason": {    "head": {      "actions": {        "$load": {          "type": "$agent.request",          "options": {            "id": "$webcontainer",            "method": "login",            "params": ["alice", "1234"]          }        }      }    },    "body": {      "header": {        "title": "Web Container 2.0"      },      "background": {        "type": "html",        "url": "file://index.html"      }    }  }}

Эта разметка гласит:

Когда просмотр загружается ($jason.head.actions.$load), сделайте запрос JSON-RPC к агенту веб-контейнера ($agent.request), где указан запрос options.

Веб-контейнер определен в $jason.body.backgroundкоторый в этом случае загружает локальный файл под названием file://index.html.

Он будет искать функцию JavaScript под названием login и передайте два аргумента ниже params ( "alice" и "1234")

login("alice", "1234")

Я только объяснил, как родительское приложение может инициировать вызовы функций JavaScript дочернего веб-контейнера, но вы также можете сделать наоборот и позволить веб-контейнеру запускать родной API родительской программы.

Дополнительные сведения см. в документации агента.

пример

Давайте вернемся к примеру QR-кода, которым я кратко поделился выше:

q5-enhI0kpKTs6F33sgyI0mS9sLqOXnHFeHI
  1. Компонент ввода нижнего колонтитула на 100% нативный.
  2. QR-код генерируется веб-контейнером в качестве веб-приложения.
  3. Когда пользователь вводит что-то и нажимает Создать, происходит вызов $agent.request действие в агент веб-контейнера, вызывая функцию JavaScript “qr”

Вы можете просмотреть пример здесь.

3. Внедрение сценария

проблема

Иногда вам может потребоваться динамически вставить код JavaScript в веб-контейнер после того, как он завершит загрузку исходного HTML.

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

Даже если вы не создаете веб-браузер, вы можете использовать метод инъекции сценария всякий раз, когда вам нужно специальное поведение для URL-адреса, содержимое которого вы не имеете контроля. Единственный способ обмена данными между нативной программой и веб-контейнером через $agent API. Но если вы не можете изменить содержимое HTML, единственный способ добавить $agent интерфейс в веб-контейнере осуществляется с помощью динамического внедрения.

Решение

Как упоминалось в предыдущей главе, $jason.body.background веб-контейнер – это просто другой agent. Это означает, что вы можете использовать то же самое $agent.inject метод, доступный постоянным агентам.

kt6qG0I8AgcTy270pNSHCE2QfZpdRRMg8SZU

4. URL Нажмите Обработка

В прошлом веб-контейнер мог обрабатывать щелчок ссылок только двумя способами:

  1. Только для чтения: Рассматривайте веб-контейнер как доступный для чтения и игнорируйте все события, такие как касание или прокрутка. Все веб-контейнеры доступны только для чтения, если вы не прикажете им вести себя как обычный браузер, как описано ниже.
  2. Обычное поведение браузера: Позвольте пользователям взаимодействовать со страницей, ведя себя как обычный браузер. Вы объявляете это с помощью настройки "type": "$default" как его action атрибут.

проблема

Оба есть Решение «все или ничего»..

  • В случае только чтения все ваши взаимодействия полностью игнорируются веб-контейнером.
  • В случае обычного поведения браузера веб-контейнер функционирует буквально как браузер. Когда вы нажимаете ссылку, вы просто перенаправляетесь по этой ссылке, обновляя страницу так же, как веб-страницу. Не было способа перехватить щелчок и вызвать какой-то родной API.

Решение

С новым веб-контейнером теперь вы можете подключить любой action на $jason.body.background веб-контейнер для обработки событий нажатия ссылки.

FhoDSEv8qQ4ZISs6syta2eU80WYBeQmFRAAS

Давайте рассмотрим пример:

{  "$jason": {    "head": {      "actions": {        "displayBanner": {          "type": "$util.banner",          "options": {            "title": "Clicked",            "description": "Link {{$jason.url}} clicked!"          }        }      }    },    "body": {      "background": {        "type": "html",        "url": "file://index.html",        "action": {          "trigger": "displayBanner"        }      }    }  }}

Здесь мы приложили "trigger": "displayBanner" к веб-контейнеру. Это означает, что когда пользователь щелкнет любую ссылку в веб-контейнере, она запускается displayBanner вместо того, чтобы разрешить веб-просмотру выполнить это.

Кроме того, если вы посмотрите на displayBanner действия, вы заметите $jason переменная. В этом случае нажатая ссылка будет передана через $jason переменная. Например, если вы щелкнули URL-адрес с названием "https://google.com", $jason будет иметь следующее значение:

{  "url": "https://google.com"}

Это означает, что вы можете выборочно запускать разные действия, проверяя $jason.url значение.

Давайте возьмем другой пример, где мы реализуем свой веб-браузер:

{  "$jason": {    "head": {      "actions": {        "handleLink": [{          "{{#if $jason.url.indexOf('signin') !== -1 }}": {            "type": "$href",            "options": {              "url": "file://key.html"            }          }        }, {          "{{#else}}": {            "type": "$default"          }        }]      }    },    "body": {      "background": {        "type": "html",        "url": "file://index.html",        "action": {          "trigger": "handleLink"        }      }    }  }}

Мы проверяем, содержит ли URL строку signin а затем выполнить два разных действия в зависимости от результата.

  1. Если он содержит signinэто открывает новое представление, чтобы позаботиться о входе нативным способом.
  2. Если он не содержит signinпросто запустите "type": "$default" так, чтобы он вел себя как обычный браузер.

Пример использования

Создание собственного веб-браузера

Теперь мы можем воспользоваться тем фактом, что новый веб-контейнер может:

  1. Возьмите a url атрибут для самозагрузки, функционируя как полноценный браузер
  2. Выборочная обработка кликов ссылок в зависимости от URL-адреса

Мы даже можем создать специальную программу для веб-браузера только с дюжиной строк JSON. Поскольку теперь мы можем перехватывать каждое нажатие ссылки, мы можем посмотреть $jason.url и выполнять любые действия в зависимости от URL-адреса.

К примеру, посмотрите на пример ниже:

iNRAFCyHHrGptiuenltF7rK902otq27ZMmTq
8vFiQuuuBm-KTt8LaNS-UEldKrWOCvJlI-0k

Слева мы видим, что нажатие ссылки ведет себя как обычный браузер ("type": "$default")

Справа мы видим, что щелчок ссылки выполняет выходной переход в другой просмотр JASON.

Всего этого можно добиться путем выборочного запуска различных действий на основе $jason.url.

Шаг 1. Подключите действие с названием visit к веб-контейнеру так:

{  ...  "body": {    "background": {      "type": "html",      "url": ",      "action": {        "trigger": "visit"      }    }  }}

Шаг 2. Выполните ответные действия внутри visit, на основе $jason.url

В следующем коде мы проверяем, $jason.url спички newest, show, askи так далее (это ссылка на верхние пункты меню). Если они это делают, мы позволяем веб-контейнеру вести себя как обычный браузер посредством настройки "type": "$default"

Если они не соответствуют шаблону, делаем нативный $href переход к новому просмотру и передача нажатой ссылки в качестве параметра.

..."actions": {  "visit": [    {      "{{#if /\\/(newest|show|ask)$/.test($jason.url) }}": {        "type": "$default"      }    },    {      "{{#else}}": {        "type": "$href",        "options": {          "url": "          "preload": {            "background": "#ffffff"          },          "options": {            "url": "{{$jason.url}}"          }        }      }    }  ]},

Ознакомьтесь с полной разметкой JSON для веб-браузера здесь (всего 48 строк!).

Мгновенная программа «Гибрид».

Когда люди обычно говорят о «гибридных» программах, они в основном подразумевают веб-программы HTML, завернутые во фрейм родной программы.

Но я имею в виду не это. Когда я говорю «гибридный», я имею в виду действительно гибридную программу, где одна программа может иметь несколько нативных и нескольких веб-представлений одновременно. Кроме того, где одно представление может иметь несколько собственных компонентов пользовательского интерфейса и веб-контейнер, отображенных в том же собственном макете.

Переход между веб-просмотром и родным видом должен быть настолько плавным, что трудно определить, где начинается и заканчивается.

KVknGIXFeBzMxUsY1pBCddiWdEub8Jl26i0g

В этом примере я создал приложение, которое отображает jasonbase.com в веб-контейнере в качестве домашней страницы.

Jasonbase – это бесплатная служба хостинга JSON, которую я создал для удобного размещения разметки JSON для приложений Jasonette.

Естественно, это просто веб-сайт, но я вставил его в Jasonette, чтобы, когда вы нажимаете ссылку, вместо того чтобы открывать веб-страницу, она создавала нативную $href переход к родному виду Jason.

Мне не нужно было касаться ни одного кода Jasonbase.com, чтобы создать это приложение.

Я просто вставил веб-сайт в Jasonette как веб-контейнер и перехватил клики ссылок, чтобы обрабатывать нативно, поэтому он мог выполнять все нативные вещи, как запуск нативных API и осуществление нативных переходов.

Вы можете проверить код здесь.

Вывод

На мой взгляд, именно это делает все это прекрасным все продумано на рамочном уровне. Вся трудная работа выполняется за кулисами.

Вместо того чтобы возлагать бремя на разработчиков программ, чтобы реализовать все с нуля:

  • Вставьте веб-просмотр в нативный макет
  • Создайте JavaScript, чтобы программа могла осуществлять вызовы функций в просмотре
  • Создание собственной архитектуры обработки событий, чтобы веб-просмотр мог инициировать собственные события в родительской программе

Решением было создать абстракцию, состоящую из:

  1. Язык декларативной разметки: для описания того, как вставить веб-просмотр в родную программу
  2. Протокол связи (JSON-RPC): чтобы разрешить простое взаимодействие между программой и ее дочерними просмотрами.

Я не утверждаю, что этот подход является лучшим решением для решения всех проблем, но я рад сказать, что это замечательное решение для моего использования.

Я пытался создать программу, которая базируется на передовой технологии, не имеющей стабильных и надежных мобильных реализаций (и непонятно, будет ли когда-нибудь мобильная реализация через природу протокола). К счастью, у него была реализация JavaScript, поэтому я мог легко интегрировать его в программу без хлопот.

В общем, это было здорово, и я доволен тем, как это получилось. Документация обновлена ​​для отображения новых функций, поэтому не стесняйтесь копать и играть.

Отказ от ответственности: с большой властью приходит большая ответственность

Я хотел бы закончить оговоркой: какой бы ни была эта новая сила, я считаю, что вам нужно сохранить баланс, чтобы создать программу с превосходным пользованием.

Некоторые могут принять это и создать целое приложение, используя только веб-просмотры, но тогда вы получите приложение, которое в основном является просто веб-сайтом, препятствующим созданию специальной программы.

Я подчеркиваю, что я не говорю, что вы всегда должны создавать приложения как с HTML, так и с нативным кодом. Я говорю, что это может быть очень полезным для многих людей в разных ситуациях. Только не переусердствуйте с этим.

Следите за нами, чтобы узнать больше

Есть много разных конфигураций, в которых собственное ядро ​​Jasonette и его дочерний веб-контейнер могут общаться, чтобы выполнять задачи творчески и мощно, и эта публикация только царапает поверхность.

В дальнейшем я планирую поделиться большим количеством этих примеров использования и учебных пособий, поэтому если вы заинтересованы, пожалуйста, следите за материалами в среде или Twitter.

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

Ваш адрес email не будет опубликован.