ПредисловиеСейчас популярность использования мобильных устройств значительно возросла, и многие компании стали использовать мобильные приложения в своих бизнес процессах, позволяя работать из любой точки мира, не привязываясь к рабочему месту.
Наша компания SoftOnIT также активно развивается. И мы ведем разработку для IOS/Android используя мобильную платформу 1С для конфигурации «Управление IT-Отделом 8», но при разработке и дальнейшей поддержки мобильного 1С приложения мы столкнулись с рядом следующих проблем:
- Очень сложно сделать красивый дизайн приложения (UI)
- Много ограничений, которые не дают сделать приложение удобным (UX)
- Недоработки платформы 1С для мобильных устройств.
- Отсутствие многопоточности.
Список проблем можно продолжать, но цель этой статьи не в том, чтобы критиковать 1С. В некоторых случаях мобильное приложение 1С идеально подходит, но, к сожалению, не в нашем. Поэтому мы начали искать другие варианты разработки мобильных приложений.
Одним из главных преимуществ 1С - это скорость разработки, поскольку приложение можно сразу собрать для устройств на Android и iOS. Поэтому мы решили попробовать заменить мобильное приложение 1С на Flutter, так как Flutter является кроссплатформенным фреймворком для разработки приложений и в нашем коллективе уже были сотрудники, знакомых с этим фреймворком.
Простой пример синхронизации
Для наглядной демонстрации синхронизации мы будем использовать чистую конфигурацию, в которой создадим объект «Дела». Во Flutter мы также создадим чистый проект, при запуске которого на первом экране будет отображаться синхронизированный список наших дел.
Создание новой конфигурации
Для начала нужно создать новую конфигурацию 1С.
В дереве метаданных создаем новый справочник «Дела» и добавляем реквизит «Выполнено» типом «Булево».
После создания справочника открываем конфигурацию в режиме предприятия (F5). В открывшемся окне переходим в список дел и создаем задания.
Отлично! Для синхронизации с мобильным приложением мы будем использовать HTTP-сервис. Создаем его, назвав, например, «API» (название можно выбрать любое). Обязательно указываем корневой URL, к которому мы позже будем отправлять запросы.
В HTTP-сервисе создаем шаблон URL. а внутри него создаем метод GET, который будем использовать для получения данных. Если хотите узнать больше о HTTP-методах, можете найти информацию в интернете.
Далее в методе GET создаем обработчик, который будет обрабатывать запросы GET, поступающих из мобильного приложения.
Сразу пропишем логику получения списка дел из базы данных 1С. Затем сформируем ответ в формате JSON, чтобы передать данные в мобильное приложение.
Функция V1GET(Запрос)
// Получение списка дел.
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| Дела.Наименование КАК Наименование,
| Дела.Выполнено КАК Выполнено
|ИЗ
| Справочник.Дела КАК Дела";
Дела = Запрос.Выполнить().Выгрузить();
// Сериализация списка дел в JSON.
ОбъектыJSON = СериализацияДелВJSON(Дела);
// Возврат ответа.
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(ОбъектыJSON, КодировкаТекста.UTF8);
Ответ.Заголовки.Вставить("Content-Type", "application/json");
Возврат Ответ;
КонецФункции
Функция СериализацияДелВJSON(Дела)
ОбъектыJSON = "";
Для Каждого Дело Из Дела Цикл
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
Структура = Новый Структура();
Структура.Вставить("name", Дело.Наименование);
Структура.Вставить("done", Дело.Выполнено);
ЗаписатьJSON(ЗаписьJSON, Структура);
ОбъектJSON = ЗаписьJSON.Закрыть();
ОбъектыJSON = ?(ОбъектыJSON = "", ОбъектJSON, ОбъектыJSON + "," + Символы.ПС + ОбъектJSON);
КонецЦикла;
Результат = "[" + Символы.ПС + ОбъектыJSON + Символы.ПС + "]";
Возврат Результат;
КонецФункции
Далее, чтобы HTTP-сервис заработал, необходимо опубликовать базу с помощью IIS или Apache. В нашем случае мы будем использовать IIS. Важно, при публикации убедитесь, что включен ранее созданный HTTP-сервис «API».
Проверка выполнения запроса GET
После реализации логики получения дел и публикации базы, можно проверить выполнение запроса с помощью программы Postman. Если вы ранее не использовали эту программу, скачайте её и в открывшемся окне введите адрес ранее опубликованной базы, добавив в конце <адрес>/hs/api/v1/.
Если адрес введен правильно, то в ответ Postman придет текст в формате JSON, содержащий список ваших дел.
Создание проекта Flutter
Теперь, когда серверная сторона полностью реализована, можно перейти к клиентской части, а именно к мобильному приложению. Приложение будет отправлять запросы GET и получать список дел в виде задач.
Для начала установите Flutter, следуя инструкции в официальной документации.
После установки Flutter, создаем новый проект и запускаем его. Мы будем использовать Visual Studio Code (MacOS) для разработки.
После создания проекта запускаем отладку на эмуляторе Android или IOS. Если Flutter был установлен правильно, откроется демонстрационное приложение «Счетчик», которое генерируется при создании нового проекта Flutter.
Сверстаем простой список задач. Для этого выполните следующие шаги:
- Откройте файл main.dart.
- Удалите лишние комментарии, чтобы код был более читаемым.
- Замените заголовок «Flutter Demo Home Page» на «Список дел».
- В классе состояния текущей страницы MyHomePageState удалите лишний код, оставив только метод build.
- Внутри виджета Scaffold в свойстве body удалите все дочерние виджеты и назначьте виджет списка ListView.
- В свойстве backgroundColor верхней панели AppBar изменим цвет. Мы будем использовать 1С-ый цвет :)
- Используйте конструктор ListView.builder, чтобы динамически создать карточки списка дел с помощью виджета ListTile.
Вот пример того, как должен выглядеть код после изменений:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.yellow,
title: Text(widget.title),
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(
title: const Text('Починить принтер'),
subtitle: const Text('В работе'),
leading: Container(
height: 10,
width: 10,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
),
);
},
),
);
}
}
Отлично! Осталось только реализовать запрос для заполнения списка реальными данными из опубликованной базы 1С.
Добавим библиотеку для работы с HTTP-запросами:
- Откройте файл pubspec.yaml.
- Найдите секцию dependencies.
- Добавьте библиотеку http версии 1.2.2.
В терминале выполняем команду актуализации библиотек Flutter.
flutter pub get
В файле main.dart импортируем библиотеку.
import 'package:http/http.dart' as http;
Теперь можно использовать библиотеку для выполнения запросов HTTP и получения списка дел с сервера. В классе состояния нашего экрана добавим новое состояние - список дел tasks, и переопределим метод initState() для выполнения HTTP-запроса при инициализации виджета.
class _MyHomePageState extends State<MyHomePage> {
List<dynamic> tasks = [];
@override
void initState() {
final jsonTasks = getJSON();
jsonTasks.then(
(json) {
setState(() {
tasks = jsonDecode(json) as List<dynamic>;
});
},
);
super.initState();
}
Future<String> getJSON() async {
final url = Uri.parse('https://<адрес>/flutter/hs/api/v1/');
final response = await http.get(url);
if (response.statusCode == 200) {
final decodedBody = utf8.decode(response.bodyBytes);
return decodedBody;
}
return '';
}
// ...
Хорошо! Теперь при открытии экрана будет происходить запрос в базу данных и заполнять ранее созданный массив дел tasks. Но как теперь отобразить полученные данные в списке? Всё очень просто:
- В виджете списка заданий в свойстве itemCount заменяем значение «10» на количество элементов в массиве tasks.length. Теперь виджет списка будет отображать столько элементов, сколько хранится в нашем массиве.
- В свойстве itemBuilder создадим две переменные: name и done, которые будем получать из массива по индексу, и уже эти переменные мы устанавливаем в значения карточки списка.
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.yellow,
title: Text(widget.title),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
final String name = tasks[index]['name'];
final bool done = tasks[index]['done'];
return ListTile(
title: Text(name),
subtitle: done ? const Text('Выполнено') : const Text('В работе'),
leading: Container(
height: 10,
width: 10,
decoration: BoxDecoration(
color: done ? Colors.green : Colors.red,
borderRadius: BorderRadius.circular(10),
),
),
);
},
),
);
В итоге у нас должен получиться следующий результат.
Заключение
Конечно, можно было бы сделать все намного структурированнее: внедрить чистую архитектуру, добавить авторизацию пользователей, использовать пагинацию при запросе списка дел и многое другое. Однако цель этой статьи - показать простую синхронизацию между Flutter и 1C. Если бы мы использовали все эти аспекты, демонстрация синхронизации стала бы значительно сложнее. Все эти подходы мы используем в нашей конфигурации «Управление IT-Отделом 8». Мы разработали собственный API и создаём новое мобильное приложение на Flutter. Вы всегда можете заказать демонстрационную версию нашего решения и проверить работу нашего API. На этом всё, удачи в разработке Flutter мобильных приложений для 1С!