- PVSM.RU - https://www.pvsm.ru -

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

Последние несколько месяцев я работаю над новым способом создания кросс-платформенных приложений для Android [1] и iOS [2] под названием Jasonette [3]. Он позволяет написать приложение от начала до конца, используя только разметку JSON.

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 1

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

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

Посмотрите видео [4], чтобы получить общее представление.

Jasonette способен осуществлять различные операции. Вы можете прописывать функции, шаблоны стили и многое другое, используя JSON-разметку [5]. Таким образом становится возможно написать нативного мобильного приложения любой сложности по схеме "Модель-Представление-Контроллер [6]"

В этой статье я раскрою только звено «Представление»:

  1. 1. Каким образом Jasonette реализует различные кросс-платформенные UI-модели в формате JSON.
  2. 2. Как он реализует переходы из JSON к Native.

Базовая структура

При детальном рассмотрении Jasonette работает как веб-браузер. Однако вместо интерпретации HTML-разметок и отрисовки представления веб-страниц Jasonette извлекает JSON-разметку и на лету отрисовывает нативное представление. Разметка при этом является всего лишь JSON-файлом, который следует заданным алгоритмам [7]. Прежде всего, он запускается с ключом $jason с двумя дочерними элементами: head и body. Выглядит это следующим образом:

{
  "$jason": {
    "head": {
      .. metadata about the document ...
    },
    "body": {
      .. actual content to be displayed on the view ..
    }
  }
}

Философия дизайна

Когда я только начинал заниматься разработкой синтаксических конструкций JSON для представления нативных структур, я столкнулся с некоторыми препятствиями:

  1. Нативная система разметки. iOS и Android не случайно вышли на рынок со своими собственными нативными интерфейсами. Макеты, созданные в эпоху компьютеров, не всегда удается приспособить для карманных девайсов. Синтаксис должен отображать макет в виде, максимально совместимом с нативной мобильной системой.
  2. Кроссплатформенность. И вместе с тем, он должен быть кроссплатформенным. К примеру, для продуктов iOS есть такая штука, как autolayout [8], а также визуальный язык форматов [9], которые, однако, не подойдут под Android, а значит, не годятся в качестве решения.
  3. Простота написания. Приложение должно легко переводиться в простую разметку JSON и также легко трансформироваться в сложную структуру.

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

  1. Вертикально прокручиваемый список
  2. Горизонтально прокручиваемый список
  3. Абсолютное позиционирование
  4. Сетка

Давайте подробнее рассмотрим первые три пункта, так как они применяются наиболее широко.

1. Разделы — Построение прокручиваемых списков

Наиболее часто применяемый шаблон пользовательского интерфейса — прокручиваемый список. В Jasonette данные шаблоны называются sections. Они бывают двух типов: горизонтальные и вертикальные, и прокручиваются горизонтально и вертикально соответственно.

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 2 Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 3

Реализация — Вертикальные разделы

Этот UI-шаблон используется для отображения данных на мобильных устройствах, пожалуй, чаще всего. На iOS, Jasonette он реализуется с помощью UITableView [10]. На Android — посредством RecyclerView [11].

{
  "body": {
    "sections": [{
      "items": [
        {"type": "label", "text": "Item 1"},
        {"type": "label", "text": "Item 2"},
        {"type": "label", "text": "Item 3"}
      ]
    }]
  }
}

На iOS вышеупоянутая разметка JSON создает UITableView с тремя UITableViewCells [12], каждая из которых содержит UILabel [13] с соответствующими параметрами text.

На Android создается RecyclerView с тремя элементами, каждый из которых представляет собой TextView [14] и отображает соответствующие параметры text.

Всё это прописано в коде без использования Storyboards [15] (iOS) или XML-файлов разметки [16] (Android), чтобы обеспечить возможность программировать каждый элемент в динамическом режиме.

Реализация — Горизонтальные разделы

С точки зрения синтаксиса горизонтальные разделы ничем особо не отличаются от вертикальных. Всё, что вам нужно сделать, — это установить «горизонтальный» тип, после чего все элементы выстроятся по горизонтали.

{
  "body": {
    "sections": [{
      "type": "horizontal",
      "items": [
        {"type": "label", "text": "Item 1"},
        {"type": "label", "text": "Item 2"},
        {"type": "label", "text": "Item 3"}
      ]
    }]
  }
}

Примечание: Синтакс горизонтального раздела кажется достаточно простым, но на самом деле это не так. Горизонтальные разделы на iOS реализуются с помощью UICollectionView [17]. Это хорошо известный механизм, но, по сути, горизонтальная прокрутка UICollectionView встраивается в исходный UITableView (который отвечает за вертикальную прокрутку). На Android, принцип реализован схожим образом, только с использованием составного RecyclerViews.

2. Элементы — Построение разметки внутри каждого компонента прокрутки

Теперь, когда стало понятно, как построен самый верхний уровень, давайте взглянем на items. Каждый раздел состоит из нескольких компонентов прокручиваемых items. Обратите внимание, что каждый элемент имеет фиксированный размер и ничего внутри самого элемента не прокручивается.

Каждый элемент может представлять собой:

  • Только один компонент — такой, как label, image, button, textarea и т.д.
  • Сочетание любых из этих компонентов

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

К счастью, iOS и Android имеют очень похожие нативные системы разметки, UIStackView [18] и LinearLayout [19] соответственно, которые в свою очередь аналогичны CSS Flexbox [20]. Так что можно считать это максимально возможным приближением к кроссплатформенности.

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

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 4 Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 5 Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 6

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

{
  "items": [{
    "type": "vertical",
    "components": [
      {
        "type": "label",
        "text": "First"
      }, 
      {
        "type": "label",
        "text": "Second"
      }, 
      {
        "type": "label",
        "text": "Third"
      }
    ]
  }]
}

То же самое и для горизонтальной разметки. Просто установите горизонтальный тип.

{
  "items": [{
    "type": "horizontal",
    "components": [
      {
        "type": "image",
        "url": "http://i.giphy.com/LXONhtCmN32YU.gif"
      }, 
      {
        "type": "label",
        "text": "Rick"
      }
    ]
  }]
}

Чтобы встроить одну разметку в другую, достаточно прописать ее как один из компонентов.

{
  "items": [{
    "type": "horizontal",
    "components": [
      {
        "type": "image",
        "url": "http://i.giphy.com/LXONhtCmN32YU.gif"
      }, 
      {
        "type": "vertical",
        "components": [{
          "type": "label",
          "text": "User"
        }, {
          "type": "label",
          "text": "Rick"
        }]
      }
    ]
  }]
}

Ради краткости я не стал говорить о стилях. Вы можете оформлять каждый компонент в отдельности, а также сам макет, пока не придадите им точно такой вид, какой вы хотите. Всё, что для этого необходимо сделать — добавить объекты style, описывающие font, size, width, height, color, background, corner_radius, opacity и т.д.

3. Уровни — «Абсолютное позиционирование»

Иногда вам может захотеться закрепить компоненты в определенных частях экрана без возможности прокрутить их. В терминологии CSS мы назвали бы это «абсолютным позиционированием». Jasonette поддерживает эту возможность через инструмент под названием layers.

В настоящее время layer поддерживает два типа дочерних элементов: image и label. Вы можете поместить их в любую область на экране, какую пожелаете. Вот пример:

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

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

{
  "$jason": {
    "body": {
      "style": {
        "background": "camera"
      },
      "layers": [
        {
          "type": "label",
          "text": "22°C",
          "style": {
            "font": "HelveticaNeue-Light",
            "size": "20",
            "top": "50",
            "left": "50%-100",
            "width": "200",
            "align": "center"
          }
        },
        {
          "type": "label",
          "text": "few clouds",
          "style": {
            "font": "HelveticaNeue",
            "size": "15"
          }
        },
        {
          "type": "image",
          "url": "https://s3.amazonaws.com/.../camera%402x.png",
          "style": {
            "bottom": "100",
            "width": "30",
            "color": "#ffffff",
            "right": "30"
          }
        }
      ]
    }
  }
}

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

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

Вот несколько примеров, на 100% составленных из вышеупомянутых UI-элементов:

После просмотра

На данном этапе вы скорее всего думаете одно из двух:
Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 8 Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 9

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

Как я уже упоминал выше, здесь описана только часть «Представление» — самая простая из трех. Но сильной стороной Jasonette является то, что вы можете пойти гораздо дальше и с помощью JSON полностью написать декларативную программу [23].

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

Если вы сумеете описать через JSON логику не только «Представления», но также «Модели» и «Контроллера» — ваши возможности безграничны.

Возможности

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

И JSON могут поступать откуда угодно — с локальных устройств, с удаленных серверов, да хоть с raspberry.pi [24]!

  • Есть веб-приложение? Если у вас уже имеется веб-приложение, вы можете мгновенно создать мобильную нативную версию для ваших приложений Node.js, Rails, Django, PHP или любого другого веб-приложения, просто отправляя запросы на ваш API.
  • Вам даже не нужен сервер: Так как весь контроллер «Модель-Вид-Управление» можно поместить в один-единственный автономный JSON-файл, фактически вы можете выбирать любое местоположение, чтобы хранить данные и работать с ними. Можно даже создать приложение, используя статический файл JSON, который работает из Pastebin или Github!
  • Превратите любой HTML веб-сайт в приложение: У Jasonette сильный парсер HTML-JSON при поддержке cheerio library [25], которая позволяет превратить любой HTML-объект в объект JSON. А что можно сделать после этого преобразования, вы уже знаете: создать нативный интерфейс из преобразованного JSON-файла! Таким образом, вы можете превратить веб-сайт, у которого даже нет API, в нативное приложение. Конечно, предпочтительнее использовать JSON при любой возможности, но все равно это круто.

Можно продолжать до бесконечности, вот лишь несколько примеров:

1) Приложение для размещения фотографий [26], которое позволяет сделать снимок с помощью камеры и загрузить его в S3, а затем опубликовать запись на своём собственном сервере, создавая веб-канал:

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 10

2) Приложение Eliza Chatbot [27] для iOS и Android на Node.js

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 11

3) Приложение Microblog [28], оснащённый функцией управления сеансами

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 12 Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 13

4) Удаленное управление ботами Slack [29]

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 14

5) Приложение-образец [30], которое превращает веб-страницы в файлы JSON, а затем в нативное приложение.

Как разработать кросс-платформенное приложение с помощью одной лишь разметки JSON - 15

Заключение

Jasonette — молодой проект. Я выложил версию для iOS [2] в открытый доступ в конце 2016-го года, а версию для Android [1] — месяцем позже.

Однако он уже обзавелся сообществом пользователей [31], принимающих активное участие в его развитии, и находится на стадии стремительного роста. Я надеюсь, что эта технология позволит расширить возможности любого пользователя (не только разработчиков) и позволит создавать приложения без особых усилий.

Звучит заманчиво? Посмотрите веб-сайт проекта здесь [32]. И последнее: вы можете найти репозитории Github здесь: iOS [2] и Android [1] (Лица, готовые сделать пожертвования проекту — радушно приветствуются!)

Автор: Everyday Tools

Источник [33]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/html/245132

Ссылки в тексте:

[1] Android: https://github.com/Jasonette/JASONETTE-Android

[2] iOS: https://github.com/Jasonette/JASONETTE-iOS

[3] Jasonette: https://www.jasonette.com/

[4] видео: https://www.youtube.com/watch?v=hfevBAAfCMQ

[5] JSON-разметку: https://docs.jasonette.com/

[6] Модель-Представление-Контроллер: https://en.wikipedia.org/wiki/Model–view–controller

[7] заданным алгоритмам: http://docs.jasonette.com/

[8] autolayout: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG

[9] визуальный язык форматов: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html

[10] UITableView: https://developer.apple.com/reference/uikit/uitableview

[11] RecyclerView: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html

[12] UITableViewCells: https://developer.apple.com/reference/uikit/uitableviewcell

[13] UILabel: https://developer.apple.com/reference/uikit/uilabel

[14] TextView: https://developer.android.com/reference/android/widget/TextView.html

[15] Storyboards: https://developer.apple.com/library/content/documentation/General/Conceptual/Devpedia-CocoaApp/Storyboard.html

[16] XML-файлов разметки: https://developer.android.com/guide/topics/resources/layout-resource.html

[17] UICollectionView: https://developer.apple.com/reference/uikit/uicollectionview

[18] UIStackView: https://developer.apple.com/reference/uikit/uistackview

[19] LinearLayout: https://developer.android.com/reference/android/widget/LinearLayout.html

[20] CSS Flexbox: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes

[21] Instagram UI: https://github.com/Jasonette/Instagram-UI-example

[22] Twitter UI: https://github.com/Jasonette/Twitter-UI-example

[23] полностью написать декларативную программу: http://docs.jasonette.com/actions/

[24] raspberry.pi: https://www.raspberrypi.org/documentation/remote-access/web-server/nginx.md

[25] cheerio library: https://github.com/cheeriojs/cheerio

[26] Приложение для размещения фотографий: https://github.com/Jasonette/s3-upload-example

[27] Eliza Chatbot: https://github.com/Jasonette/eliza-example

[28] Microblog: https://github.com/Jasonette/token-authentication-example

[29] Удаленное управление ботами Slack: http://blog.jasonette.com/2017/01/17/build-a-slackbot-with-jasonette/

[30] Приложение-образец: https://github.com/gliechtenstein/iosdevweekly.json

[31] сообществом пользователей: http://blog.jasonette.com/2017/01/12/Jasonette-2016-in-review/

[32] здесь: https://www.jasonette.com

[33] Источник: https://habrahabr.ru/post/322216/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best