Сооснователь Wheely о разработке такси-приложения для трёх основных мобильных платформ Статьи редакции

Соучредитель и глава по продукту сервиса личных водителей Wheely Павел Бочаров написал для ЦП колонку о процессе разработки нового приложения для iOS, Android и Windows Phone — как происходила разработка новой версии, каким образом разработчики планировали упростить заказ водителя и сделать приложение быстрее.

Павел Бочаров

Привет. Меня зовут Павел Бочаров. Я работаю в Wheely с момента основания, занимаюсь организацией дизайн-процесса и курирую разработку нашего основного (по численности пользователей) продукта — приложения для пассажиров.

5 августа, после долгого семимесячного перерыва, вышла новая версия приложения Wheely. Ниже — краткий рассказ о том, что мы делали все это время.

Задача

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

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

Контекст

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

  • Привычный облик первого экрана в целом должен сохраниться (были и другие варианты, включающие переделку всего, но революцию решили приберечь).
  • Чем меньше действий совершит пользователь, чтобы посмотреть расчетное время прибытия машины, тем лучше. Часто (особенно, если клиент не новый) это именно та информация, на основе которой он принимает решение: заказывать машину или нет.
  • Выбор тарифа, сделанный пассажиром при первом заказе должен сохраняться, избавляя его от лишних действий при следующих заказах.
  • Мы любим и уважаем стандарты платформ, например, HIG или материальный дизайн. Можно немного развернуть:
  1. приложение должно быть «нативным» (сливаться с окружающей его средой той или иной платформы, в каком-то смысле быть похожим на стандартные приложения);
  2. меньше информации, больше практической пользы;
  3. не мельчить (понятно, что мы смотрим на решения наших конкурентов;
  4. на их примере мы, в частности, понимаем то, как делать не стоит);
  5. грамотные сообщения об ошибках;и другие скучные и важные мелочи.
  • (Для iOS) Необходимо пересесть на Google-карты. В старой версии мы использовали карты от Apple, но для России на них до сих пор нет очертаний домов, поэтому поверх мы накладывали стилизованные под стандартные карты тайлы (небольшие кусочки карт) от Mapbox. Это приемлемое и быстрое решение, но, к сожалению, оно, во-первых, не дешевое (Mapbox стоит тем дороже, чем выше количество пользователей), во-вторых, не самое красивое (стили карт для России и остального мира отличаются).

Реализация

Мы спроектировали процесс заказа автомобиля заново, учитывая исходные данные. Если утрированно говорить о количестве, то для заказа теперь достаточно двух нажатий, вместо трех. Но, понятно, что один «тап» — разница смешная, и количество здесь не так важно. Важны качественные изменения.

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

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

Под обновленной внешней оболочкой, которую видит конечный пользователь, скрывается абсолютно новый механизм. Для гурманов: мы переписали большую часть ключевого iOS-кода на Swift, переосмыслив при этом логику и структуру основных алгоритмов и моделей данных. Мы написали отдельный свифтовый фреймворк CoreWheely. Это библиотека программного кода, которую мы будем использовать и в других проектах (например, в приложении для водителей).

Помимо этого, мы, традиционно, исправили старые ошибки и добавили немного новых, чтобы было не скучно.

Сложность

Это первая версия приложения, которую мы подробно проектировали «на бумаге» и тестировали на прототипах, пытаясь выявить возможные нюансы на раннем этапе. Из-за оставленных без внимания узких мест увеличивается время разработки и, главное, стремительно сокращается количество красоты.

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

Техническая сложность заключалась в четырех основных задачах:

  • Спроектировать новый клиент-серверный API (программный интерфейс «общения» мобильного приложения и сервера). Новый API, был необходим для того, чтобы показывать пользователям информацию о доступных тарифах и времени прибытия машины до того момента, как они выберут адрес подачи.
  • Добиться того, чтобы UI был плавным: плавные анимации, custom transitions (механизм для построения интересных нестандартных переходов с одно экрана на другой), custom parent view controllers (способ организации сложных экранов).
  • Перейти на Swift. Приложение для iOS мы хотели переписать на Swift, максимально используя возможности функционального подхода, которого нам так нехватало в Objective-C. Короче говоря, предстояло переписать все модели данных, алгоритмы и клей между ними.
  • Перейти на Google-карты. Карта — основной элемент в нашем приложении, при этом на стардантный системный элемент навешено много нестандартного поведения. Например, пин-булавка, указывающая на место подачи, должна быть то зафиксирована (пользователь должен двигать саму карту под пином), то, наоборот, прикреплена к конкретной географической координате и двигаться вместе с картой. Программный интерфейс эпловых и гугловых карт отличается, а переход с одной на другую, в случае если есть какое-то нестандартное поведение — задача непростая.

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

В процессе работы над новыми интерфейсами, самым интересным было реализовать задуманный проект, его концептуальную модель, с минимальными отклонениями, как можно более «чисто» (с точки зрения конкретного программного кода).

Для этого мы создали собственную инфраструктуру добавления к экранам «оверлеев» (информационных панелей, которые накладываются поверх базового экрана). «Оверлеи» могут брать на себя роль как визуального, так и функционального расширения.

Структурно приложение стало более модульным и приобрело новые механизмы композиции. Эти изменения позволят нам увеличить скорость разработки, и уменьшить вероятность возникновения ошибок.

Никита Кукушкин, iOS-разработчик

После перехода на Swift многие заметили, что из уголка айосников стало лететь очень много мата. Все из-за багов компилятора и крашей Xcode, но это было еще на Swift 1.0, сейчас ситуация намного лучше.

У нас не было времени переписывать 100% кодовой базы на Swift, поэтому пришлось применять хитрости: мы написали «оболочки», которые позволяют новым моделям данных вести себя как старые. В результате мы смогли использовать новые модели в старом Objective-C коде практически без изменений.

Александр Рубин, iOS-разработчик

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

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

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

Сергей Шулепов и Сергей Дмитриев, Android-разработчики

Основным вызовом в WP приложении было воссоздание UX, максимально приближенного к iOS и Android версиям, сохранив при этом оригинальный для WP пользовательский интерфейс.

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

Немало проблем доставило несоответствие описанному и ожидаемому поведению некоторых элементов. Однако все эти проблемы удалось решить или обойти благодаря гибкости платформы и большому сообществу.

Александр Шкрыль, разработчик приложения для Windows Phone

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

Для компенсации ее утраты нам пришлось отказаться от первоначальной идеи минималистичного текстового меню тарифов на первом экране, заменив его отшлифованными иконками.

Что дальше

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

Статистика

На закуску немного свежих чисел (на примере проекта для iOS):

  • Разработка новой версии заняла 7 месяцев и 13 дней, суммарно — 225 календарных дней или 147 рабочих дней.
  • За это время мы сделали 3 551 коммитов (зафиксированных «изменений» проекта), которые затронули 1 847 файлов.
  • Суммарно, мы добавили 34 780 строк кода, при этом удалили гораздо больше (это всегда радует) — 83 431 строк, включая сторонние библиотеки, которые используются в проекте.

Для Android и Windows Phone эти показатели скромнее, но, поскольку эти числа все равно бесмысленно оценивать сами по себе, выглядит красиво:

  • Android: 1 376 коммитов, изменивших 710 файлов; cуммарно — 13 074 добавленных строк кода и 10 075 удаленных.
  • WP: 338 коммитов, изменивших 1 363 файлов; cуммарно — 12 429 добавленных строк кода и 9 282 удаленных.
0
33 комментария
Написать комментарий...
Anton Sinelnikov

Добрый день, в некоторых ваших s-классах очень бедная комплектация, и нельзя откинуть заднее сиденье. Это касается и 221 и 222 кузовов. Сделайте пожалуйста возможность указать при вызове, что опция откидывающихся задних сидений обязательна. Очень раздражает, когда заказываешь машину за минималку 3000р, а сидеть сзади приходится на табуретке. Спасибо.

Ответить
Развернуть ветку
Alexey Kokin

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

Ответить
Развернуть ветку
Anton Sinelnikov

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

Ответить
Развернуть ветку
Алексей Сташков

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

Ответить
Развернуть ветку
Anton Sinelnikov

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

Ответить
Развернуть ветку
F.J.
Ответить
Развернуть ветку
Sergey Sarkisyan
Android терпеть не может плавный пользовательский интерфейс

В Logcat не смотрели, как часто GC у вас срабатывает?
P.S. очень странно в одном абзаце читать про проищводительность и паддинги.

Ответить
Развернуть ветку
Сергей Пепякин

С GC никаких проблем не было. А вот насчет производительности и паддингов в одном абзаце — ничего странного: смена паддингов в обычных вьюхах может повлечь за собой процесс переразметки (relayout) всего дерева вьюшек. В глубоковложенных и сложных иерархиях это может быть очень дорогостоящей операцией.
В случае с картами гугла, установка паддинга может занимать до 5-7 мс. Это, как я уже говорил, связанно с вовлечением в процесс IPC (см. com.google.android.gms.maps.internal.IGoogleMapDelegate.zza#setPadding). В контексте анимации сложной иерархии можно получить неплохое проседание фрейм рейта.

Ответить
Развернуть ветку
Mike Kosulin

Мрачноватый у вас дизайн на WP.
Кст, круто, что в отличие от Uber вы указываете цвет машины.

Ответить
Развернуть ветку
Pavel Bocharov

Вы правы, WP мы уделяли меньше времени, чем другим платформам (аудитория существенно меньше). Но скоро и эту версию подтянем.

Ответить
Развернуть ветку
Илья Ермаков

А почему вы решили использовать именно Google карты, а не Яндекс? Ведь они еще лучше бы прижились в приложении. Яндекс - российская компания и карты у нее самые лучшие для нашей страны.

Ответить
Развернуть ветку
Pavel Bocharov

Ничего против карт Яндекса не имею, в Москве сам пользуюсь. Жалко только, что они не векторные. Однако, согласно п. 2.3.7.3. условий использования сервиса “API Яндекс.Карты” пользователь не имеет права “создавать на основе Сервиса системы мониторинга транспортных средств, отображающих информацию в реальном времени, и любые другие услуги, связанные с управлением и диспетчеризацией транспортных средств.“

Ответить
Развернуть ветку
Ivan Samsonov

а) Wheely работает не только в России
б) Неудобная лицензия у Яндекс карт

Ответить
Развернуть ветку
Virl

Привет.
Насчет анимаций в андроиде: я развиваю свою опенсорсную библиотеку vcdroid, которая заменяет активити и фрагменты на кастомные вью контроллеры, портированные из iOS с фреймворком анимации.

В итоге это дает кастомные анимации без тормозов и создания активити, работающие начиная с 4.1

Посмотреть можно здесь: https://github.com/virl/vcdroid

Видео:
http://www.youtube.com/watch?v=4S4vr23qB7k
http://www.youtube.com/watch?v=dqelBt0HQJs

Ответить
Развернуть ветку
Dmitry Volostnov

А можете дать статистику сколько у вас пользователей с iOS, Android и Wp, плиз

Ответить
Развернуть ветку
Pavel Bocharov

Могу сказать относительные цифры: 80% с iOS, 18% с Android и 2% с WP.

Ответить
Развернуть ветку
Dmitry Volostnov

спасибо!

Ответить
Развернуть ветку
Михаил Виноградов

Молодцы, что ради 2% целую версию сделали. По-чесноку, можно было и пренебречь. Крутые.

Ответить
Развернуть ветку
Pavel Osadchuk

Не хотите попробовать замутить бота telegram для вызова такси?

Ответить
Развернуть ветку
Михаил Виноградов

Мы думаем об этом в "Таксилёте". Но у нас нет приложения. Неужели удобнее через мессенджер, чем через приложение? Чем?

Ответить
Развернуть ветку
Pavel Osadchuk

не нужно ставить приложение.
можно использовать морфологию.

юзкейс:
1) пользователь хочет вызвать такси и он использует Telegram.
2) переходит по ссылке telegram.me/TaksiletBot например с вашего сайта
3) пишет "Подайте такси на улицу Петрова, дом 6 сегодня в 17:00"
4) Бот вычленяет команду "подать"+"такси", адрес "улица Петрова, дом 6", дату "22.08.2015 17:00"
и кидает подтверждение "Ваш заказ: 22.08.2015 17:00, улица Петрова дом, 6. Поедем в Пулково. Все верно?". Появляется клавиатура "да"/"нет"
5) Если необходимо - начинаем диалог с пользователем "Куда подать?" "Какой класс?" "Дайте телефон" и т.п.
6) На каждое сообщение в Backend формируем заказ
5) Предлагаем пользователю "подтвердить / изменить / отменить" и запускаем в обработку

Юзкейс 2:
У таксиста Telegram. Ему приходит позиция (локация в Telegram) заказа + уточнение + клавиатура "принять/отклонить". Принять - он взял заказ/отклонить не взял.

Это вряд ли удобнее чем приложение (в приложении можно много придумать и визуально изобразить) но создать это сильно быстрее чем приложение и намного дешевле. Если интересно, можем попробовать что-нибудь собрать с www.leecero.com

Ответить
Развернуть ветку
Михаил Виноградов

интересно. отправил коллеге - возможно, свяжется!

Ответить
Развернуть ветку
Алексей Калаверин

"Пробовать мутить" - не для этих ребят.

Ответить
Развернуть ветку
Stanislav Schminke

Очень печально, что нет поддержки Blacberry. Приходится у жены просить постоянно яблокофон.

Ответить
Развернуть ветку
Александр Лисовой

BB10 умеет в Android приложения.

Ответить
Развернуть ветку
Давид Давыдов

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

Ответить
Развернуть ветку
VoipClub

Нах. вам приложение?
Вы разве еще на плаву?
:)

p/s: судя по дизайну, гет отдает чуток

Ответить
Развернуть ветку
Valery Mishurinsky

Юикс юиксом, но почему в описании пользовательского сценария на практически одинаковых скриншотах разные по форме кнопки?

Ответить
Развернуть ветку
Pavel Bocharov

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

Ответить
Развернуть ветку
Артём Фролов

На чем вы сделали прототипы с описанием каждого экрана? Это я так понимаю софт специальный?

Ответить
Развернуть ветку
Vitaly Baev

Похоже, что это Sketch

Ответить
Развернуть ветку
Pavel Bocharov

Да, в Скетче

Ответить
Развернуть ветку
Mike Kosulin

в обновленном фш, насколько я понимаю, можно сделать так же

Ответить
Развернуть ветку
30 комментариев
Раскрывать всегда