Comments 9
Скажите пожалуйста, у Вас до сих пор свайп вниз не сам получает баланс, а запрашивает отправку пуша с балансом?)
Спасибо за статью. Расскажите, пожалуйста, как вы работаете с формами ввода.
Как и откуда тянутся данные для условного dropdown?
Можете привести пример, как сейчас выглядит блок events для связанных полей? Если выбор в одном dropdown должен повлиять на данные в другом dropdown. Например, выбор города в одном dropdown, а другой dropdown должен отображать список улиц (в идеале подгружать с сервера справочник улиц для выбранного города).
Как работает хендлер Submit? Есть ли какой-то контракт, описывающий какой объект (JSON) должен отправляться из формы на сервер и как форма должна реагировать на условный 400 Bad Request?
Отвечу по пунктам.
1. Модель ответа сервера сразу включает в себя описание экрана с бизнес-данными. Обновление данных на форме происходит путём обновления экранной формы или компонента с помощью ответа от сервера.
2. Расскажу на примере двух текстовых полей и пуллеров. Снизу JSON, который демонстрирует похожую реализацию.
{
"screenId": "Settings",
"navigation": {
"title": "Адрес клиента"
},
"fieldSet": [
{
"controlId": "textFieldCity",
"component": "TEXT_FIELD",
"text": "Москва",
"events": [
{
"event": "TAP",
"action": {
"type": "SHOW",
"receiver": "pullerChooseCity"
}
},
{
"event": "CHANGE",
"action": {
"type": "SCREEN",
"subtype": "REPLACE",
"url": "rest\/v3\/screen\/ChosenCity",
"body": {
"city": "pullerChooseCity"
}
}
}
]
},
{
"controlId": "pullerChooseCity",
"component": "PULLER",
"data": [
{
"title": "Москва",
"pullerId": "50102"
},
{
"title": "Санкт-Петербург",
"pullerId": "12300"
},
{
"title": "Самара",
"pullerId": "00000"
}
],
"events": [
{
"event": "TAP",
"action": {
"type": "CHANGE",
"receiver": "textFieldCity"
}
}
]
},
{
"controlId": "textFieldStreet",
"component": "TEXT_FIELD",
"events": [
{
"event": "TAP",
"action": {
"type": "SHOW",
"receiver": "pullerChooseStreet"
}
}
]
},
{
"controlId": "pullerChooseStreet",
"component": "PULLER",
"data": [
{
"description": "Щусева улица",
"pullerId": "2"
},
{
"description": "Малая бронная улица",
"pullerId": "1"
},
{
"pullerId": "5",
"description": "Арбат улица"
},
{
"description": "Кутузовский проспект",
"pullerId": "6"
},
{
"description": "Люблинская улица",
"pullerId": "999"
}
],
"events": [
{
"event": "TAP",
"action": {
"type": "CHANGE",
"receiver": "textFieldStreet"
}
}
]
}
]
}
Этот JSON и есть ответ сервера при открытии экранной формы. Что он содержит?
В текстовом поле textFieldCity прописывается событийная обработка: при тапе на него нужно показать пуллер выбора города – pullerChooseCity. В «событийке» пуллера прописано, что нужно изменить текстовое поле textFieldCity значением, на которое тапнул пользователь в пуллере. В этом случае у нас произойдёт простое заполнение текстового поля выбранным значением. Однако для того, чтобы подгрузить улицы для выбранного города, необходимо провести сетевой запрос, который обновит экранную форму. Для этого у текстового поля textFieldCity в «событийке» есть событие CHANGE, которое срабатывает при изменении текстового поля. В этом случае при изменении нужно вызвать запрос POST rest\/v3\/screen\/ChosenCity и ответом от него произвести операцию над экраном SCREEN – REPLACE. Соответственно, с точки зрения разработки мы ожидаем, что с бэка придёт экранная форма с текстовым полем textFieldStreet и пуллером pullerChooseStreet, актуальными для выбранного города в текстовом поле textFieldCity.
3. Что касается передачи данных с формы мобильного приложения на бэк – как такового жёсткого контракта нет. В любом действии, которое подразумевает сетевой запрос, есть объект "body", который представляет из себя формат type obj = {[keys: string]: any};. При этом данные из конкретного компонента будут подставляться по его идентификатору. На примере кейса выше:
{
"event": "CHANGE",
"action": {
"type": "SCREEN",
"subtype": "REPLACE",
"url": "rest\/v3\/screen\/ChosenCity",
"body": {
"city": "pullerChooseCity"
}
}
}
В этом случае выполняется вот такой запрос на бэк (лог из мобильного приложения):
https://{some-host.com}/rest/v3/screen/ChosenCity
request.headers = {
Accept-Language = ru
Content-Type = application/json
Content-Length = 16
x-sber-date = 2023-01-24T13:57:46+03:00
Accept-Encoding = gzip
}
request.httpMethod = POST
request.body = {
"city" : "50102"
}
В случае возникновения транспортной ошибки (недоступность бэка) на мобильном приложении будет показана стандартная ошибка с шаблонным текстом. Все бизнес-ошибки мы рекомендуем командам обрабатывать двумя способами:
1. Отрисовывать новый экран, где начнётся альтернативный сценарий или подсветятся проблемные зоны.
2. Возвращать общую модель ошибки с бэка, для которой в мобильном приложении также есть обработчик. В конечном счёте покажется системный диалог с сообщением для клиента.
{
"code": 1001,
"message": "Произошла ошибка."
}
Что вы имеете в виду, говоря о хендлере SUBMIT?
Судя по описанию, на базе текущих компонентов можно сделать что-то более-менее простое.
Когда речь заходит о сложных анимациях, медиаконтенте и интерактиве, тут SDUI не поможет и все равно надо подключать тяжелую артиллерию нативщиков.
Отсюда вопросы :)
Что за продукты вы уже вывели и какие планируете выводить? Можно посмотреть на эти экраны - насколько они зрелые и интересные по дизайну?
И кто, как не нативщики, делают новые компоненты для платформы? (точно ли тут есть экономия?)
Какое сейчас у вас соотношение тех, кто делает натив, и кто разрабатывает продукты на SDUI?
Что будете дальше делать со сложными интерфейсами, которые сейчас не можете реализовать с помощью SDUI, а конкуренты за счет натива могут?
Сейчас в части продуктов на этом решении у нас выведены «Подбор кредита», «Подключение АУСН», раздел «Налоги и взносы» в виджете «Мои дела» и список заказов для отраслевого решения «Транспорт».
Интерес к решению внутри банка достаточно высок у команд, которые испытывают трудности в найме мобильных разработчиков, поэтому новые продукты на SDUI появляются каждый квартал. Всё правильно, UI и UX в случае применения SDUI достаточно ограничен, не всё можно реализовать с таким подходом. Уже реализованные экраны как раз представлены в статье в разделе «Результаты». Конечно, это не всё, но принципиально именно эти экраны мы сейчас умеем делать.
Безусловно, именно мобильные разработчики создают фреймворк в СберБизнес. Сейчас в команде, которая делает решение, по два человека разработки с iOS и Android соответственно. Нативные формы у нас пилят несколько десятков команд, в каждой примерно по одному разработчику iOS и Android. Вопрос экономии очень относителен. Те, кто уже вывел формы на нативе, не особенно хотят переезжать на SDUI, но это и не требуется. Однако, как упомянуто в статье, примерно 80 % существующих экранов можно сделать на нашем фреймворке. То есть у восьми из десяти новых команд, которые хотят появиться в СберБизнес со своим продуктом, нет необходимости в найме мобильных разработчиков для старта MVP и проверки ценности функциональности в мобильном формфакторе.
Мы активно развиваемся и наполняем фреймворк новыми фичами на основе CR от команд и развития дизайн-системы. Какие-то сценарии реализовать на SDUI не получится, и нужно прибегать к нативным разработчикам. Это решение мы оставляем на откуп продуктовым командам. По опыту, команды руководствуются P&L продукта в мобильном приложении. Если рентабельность продукта или её перспективы позволяет нанять разработчиков, то нативу быть!
Возможно, это опечатка: «При этом у кнопок также есть состояния «кликабельна» или «некликабельна», то есть основная или альтернативная».
Обычно в дизайн-системах кнопки могут быть основными и альтернативными (второстепенными, третьестепенными), но при этом каждая из них может быть кликабельной и некликабельной (disabled). А в этом предложении как будто приравнены кликабельные кнопки к основным, а некликабельные к альтернативным.
Server-driven UI, «Триплекс» и JSON: как Сбер сервисы в мобильные приложения выводит