Меня зовут Сухоруков Роман, я сотрудник отдела мобильной разработки в компании «1С-Рарус».
Мы занимаемся разработкой тиражных решений на платформе 1С. Наши приложения ориентированы на широкий круг пользователей.
-
На сегодняшний момент наши приложения имеют более 5 000 активных платных подписок в App Store и Google Play.
-
Наши приложения установили более 3 000 000 пользователей.
-
25 000 из них поставили нам оценку ~ средний бал 4.5 (достаточно неплохой показатель)
-
В разное время наши приложения входили в Топ 10 в 88 странах мира в своих категориях.
Это наши продукты:
-
Приложение Boss – для автоматизации малого и среднего бизнеса;
-
Fitness – приложение для занятий спортом в зале и дома;
-
Приложение Budget – помощник учета личных финансов;
-
Приложение Diets – поможет составить/ подобрать оптимальную диету по запросам пользователя.
Мобильные интерфейсы с использованием HTML/CSS/JavaScript
Любое успешное приложение должно быстро и эффективно решать проблему пользователя, и, к тому же, должно иметь приятный, красивый, функциональный и понятный интерфейс.
B своих решениях мы чаще всего используем интерфейсы на стеке HTML / CSS / JavaScript. Применение этого стека технологий дает нам большие возможности, и в принципе наши интерфейсы могут в какой-то степени даже конкурировать с интерфейсами нативных приложений.
Пример формы из приложения Fitness – это форма выполнения тренировки.
-
В начальных версиях она была реализована строго с применением инструментария, предоставляемого платформой 1С, и выглядела так, как показано слева.
-
А справа можно увидеть, как нам удалось её улучшить с помощью HTML.
Я думаю, разница очевидна – форма стала более красивой, более удобной, интерактивной и, в принципе, смотрится намного живее.
Календарь в мобильном приложении 1С
Сегодня я хотел бы поделиться некоторыми нашими наработками в этой области на примере вот такой формы календаря для мобильного приложения на 1С.
Форма календаря представляет собой динамический список месяцев, который при нажатии на дату календаря трансформируется в список задач.
Исходники этой формы можно скачать в моей публикации и познакомиться поближе.
Рассмотрим ее логику работы:
-
у нас есть динамический список месяцев, который в один момент времени хранит данные за 6 месяцев (три месяца, которые мы видим на экране и 3 месяца, выходящие за пределы экрана);
-
все остальные данные подгружаются по мере необходимости – во время прокрутки пользователем динамический список генерирует события, которые мы перехватываем на форме 1С, и в ответ отправляем скрипту на JavaScript необходимые ему данные (например, данные за следующий месяц).
Так структурно выглядит форма календаря в JavaScript:
-
у нас есть базовый класс View, который отвечает за отрисовку всех элементов на экране;
-
от него наследуются три класса – Calendar, Month, Task.
Класс Calendar, собственно говоря, реализует механизм динамического списка – при прокрутке по достижении предельного положения генерируется событие «MonthRequest», которое передает на форму 1С дату месяца, данные которого нам необходимо получить.
Класс Month может быть в двух режимах работы:
-
закрытый режим, когда пользователь видит перед собой месяц полностью;
-
и режим списка задач за день.
В момент нажатия на любую дату месяца на форме 1С генерируется событие «GetTasks», по которому мы передаем список задач на эту дату. Впоследствии представление месяца разворачивается на весь экран и становится списком задач.
Класс Task – это представление задачи, которое содержит ссылку 1С на элемент справочника «Задачи» и дату для отображения в списке.
Механизм взаимодействия
Чтобы реализовать такую логику, нам необходимо иметь возможность отправлять на HTML-форму данные (большие данные, не только примитивы) и получать обратную связь от формы в виде событий. Этим в форме календаря как раз и занимается подсистема конвертации.
Основное назначение подсистемы конвертации – это:
-
запуск кода JavaScript и получение переданных параметров из кода 1С;
-
и генерация событий на форме 1С.
Подсистема конвертации использует для этого два полезных события поля HTML-документа – это:
-
«ДокументСформирован» – событие, которое возникает, когда у нас в память полностью загружены структура HTML-документа и все скрипты, и мы можем обращаться к JavaScript-коду из кода 1С. Мы используем это событие для инициализации формы и её заполнения данными.
-
«ПриНажатии» – событие, которое возникает перед началом перехода по ссылке в поле HTML-документа, в него мы будем получать все события, которые генерируют HTML-интерфейс.
Выполнение JavaScript-кода из 1С
Чтобы передать какие-то значения, запустить JavaScript-код из кода 1С, нам необходимо воспользоваться свойством поля HTML-документа defaultView.
Свойство defaultView становится доступным на клиенте, когда документ полностью сформирован и загружен в память (после события «ДокументСформирован»).
Свойство defaultView соответствует объекту window в JavaScript и, по сути, является глобальным контекстом нашего скрипта.
Строго говоря, с помощью свойства defaultView мы можем напрямую из кода 1С вызвать любую функцию JavaScript. Но передавать в качестве параметров и получать в результате можем только примитивы – такие, как Число, Булево или Строка.
Но поскольку нам этого мало, мы путем сериализации в JSON передаем все, что угодно – для этого используется подсистема конвертации.
Организация обмена данными с полем HTML-документа
Но предварительно мы приводим к определенному формату все объектные данные и данные, несериализуемые в JSON по умолчанию – например, дата становится структурой с двумя полями – тип и значение, после чего полученные данные сериализуются в JSON.
Казалось бы, мы получаем строку, которую уже можно передать и выполнить на стороне JavaScript. Но на самом деле, это не так – мобильная платформа может передавать не все строки. Если в строке присутствуют фигурные скобки, переносы строк, какие-то непечатаемые символы, то она будет проигнорирована и функции JavaScript будет передано пустое значение, как будто мы вообще ничего не передавали. Поэтому дополнительно мы строку JSON кодируем еще в URL.
И на стороне JavaScript это преобразуется обратно – средствами подсистемы конвертации выполняются обратные преобразования и создаются необходимые нам сущности для работы на форме.
Таким образом мы можем передавать не только примитивы, но и практически любые данные – структуры, массивы, даты, ссылки на справочники и документы.
Например, в форме календаря ссылка на справочник «Задачи» передается в объект TaskRef, который содержит в себе идентификатор и представление ссылки. Получается, что мы с таким объектом можем практически работать так, как если бы мы работали из кода 1С на клиенте со ссылкой.
Генерация события из кода JavaScript
Теперь о получении событий. Как я уже говорил, все события мы получаем в обработчике «ПриНажатии», который срабатывает перед началом перехода по гиперссылке.
Но поскольку, при прокрутке календаря необходимо вызвать это событие программно, мы можем выполнить переход средствами JavaScript.
В этом нам поможет объект location, а точнее, его метод assign, куда мы передаем URL перехода – только в нашем случае это будет не просто URL, а сериализованное в JSON и кодированное в URL описание случившегося события.
На формуле календаря это выглядит примерно так:
-
мы вызываем метод assign, которому передаем сериализованную структуру с полями name и parameter – поле name содержит имя события, которое необходимо запустить на форме 1С, а поле parameter содержит передаваемый параметр;
-
плюс ко всему перед сериализованной строкой добавляем URL-схему и домен – это необходимая деталь, потому что без домена событие «ПриНажатии» может быть просто проигнорировано платформой.
На слайде показана строка, которая генерируется при получении от динамического списка календаря запроса события «MonthRequest» для вывода следующего месяца.
Получение данных события и их обработка
Строку с событием мы получаем в процедуре «ПриНажатии» в свойстве Href переданного параметра «ДанныеСобытия».
Вот так выглядит значение свойства href при получении данных от JavaScript-события – в данном случае, мы от динамического списка календаря в подсистему конвертации получили запрос события «MonthRequest», которое должно вывести данные за следующий месяц, и в качестве параметра передана дата 01.06.2020.
Как вы видите, здесь это значение уже автоматически декодировано из URL-формата, то есть нам достаточно только десериализовать и восстановить объектные значения.
На слайде показано, как выглядит обработчик оповещения формы календаря – здесь мы обрабатываем все события.
На основании структуры, которая передается в событии «ПриНажатии», мы запускаем процедуру «Оповестить» и оповещаем все обработчики оповещений 1С о случившемся событии – передаем имя события и параметр.
Например, если обрабатывается событие «MonthReguest», мы запускаем процедуру «addMonth», которая добавляет новый месяц в список календаря, а противоположный месяц удаляется с формы. Таким образом у нас динамический список всегда хранит только шесть месяцев.
При клике на определенный месяц календаря возникает событие «GetTasks», чтобы его обработать, мы передаем список задач методу «showTasks».
Преимущества использования web-стека
Формы web-стека дают нам дополнительные возможности, такие как:
-
возможность детально проработать любой пиксель на экране, любой отступ, генерировать анимацию каждого элемента;
-
мы можем обрабатывать touch-события – любой жест пользователя, свайп, движение одним-двумя-тремя пальцами тоже можно перехватить на форме и создать функциональный отзывчивый интерфейс;
-
это работает быстрее, чем форма 1С – например, в системе Android нажатия по ссылкам проходят без задержки. В iOS же при каждом клике генерируется задержка порядка полсекунды, в этот момент отрабатывает встроенная анимация нажатия Safari;
-
есть огромное количество готового кода, уже адаптированного под мобильные экраны – можно использовать любой фреймворк, который существует на JavaScript, мы в форме календаря для создания анимаций используем jQuery.
Как я и обещал, ссылка на исходный код календаря – кому интересно, можете посмотреть.
*************
Данная статья написана по итогам доклада (видео), прочитанного на INFOSTART MEETUP Krasnodar.