Несколько месяцев назад в App Store и Google Play вышло большое обновление мобильного банка R-Mobile для клиентов РайффайзенБанка.
Этим проектом команда e-Legion занимается уже более двух лет, и в данном посте мы хотим рассказать о технических особенностях разработки. Наш опыт будет полезен тем, кто хочет писать большие, сложные, долгоживущие и успешно развивающиеся мобильные проекты для реального мира.
Вместе с пользователями мы хотим сделать R-Mobile еще лучше, поэтому будем рады конструктивным отзывам на специальной странице или в комментариях к посту.
Ну а за техническими подробностями просим под кат.
Веб-сервисы
Отличительной особенностью данного проекта является то, что взаимодействие с веб-сервисами осуществляется с помощью SOAP. Это было жёсткое ограничение со стороны технической команды заказчика, которое не обсуждалось и с которым надо было как-то жить. Несмотря на ряд недостатков («фе, распухший XML-based протокол в 2014 году»), использование этого протокола в умелых руках способно существенно ускорить реализацию доменной модели, слоя работы с API, а также создание mock-сервисов (о них чуть ниже). А всё дело в том, что для описания SOAP-сервисов существует устоявшийся и общепринятый язык: WSDL.
В теории, наличие готовых WSDL-файлов (они имелись в наличии и в нашем случае) для веб-сервисов позволяет одной командой (или нажатием кнопки, кому что больше нравится) сгенерировать всё вышеперечисленное и выкинуть из головы заботу о довольно большом куске архитектуры приложения. На практике это тоже возможно, но, в нашем случае, всё далеко не так безоблачно.
Дело в том, что SOAP — довольно старый протокол, который интенсивно использовался в начала 2000-х, а позже, к моменту, когда распространение получили современные мобильные платформы, он был почти целиком вытеснен более простым и гибким RESTful-подходом. В результате, инструментарий для работы с SOAP и WSDL на сегодня практически весь выглядит довольно устаревшим, а клиентских библиотек и генераторов кода, например, для Cocoa, очень мало. И те, что есть, выдают код довольно сомнительного качества.
В самом начале мы использовали сервис Sudz-C. На момент старта проекта он был бесплатным и позволил очень быстро получить работающий прототип. Сетевой код, который идёт с ним в комплекте (работает поверх обычного NSURLConnection, без AFNetworking и прочих штучек), пришлось серьёзно переработать, но результат пока всё равно далёк от идеала.
Позже, при обновлении приложения и добавлении новых классов сервисов и модели, мы напрямую использовали XSLT-шаблоны из исходников Sudz-C, которые мы слегка доработали под себя.
Для тех, кто сегодня начинает разработку приложения, работающего с SOAP, я бы советовал посмотреть в сторону MWSC/pico. Этот проект использует AFNetworking, и вообще, на первый взгляд, сделан более качественно.
Доступ к тестовой среде
Ещё одна особенность проекта — закрытая тестовая среда: служба безопасности заказчика категорически против того, чтобы открывать доступ к сервисам снаружи до того, как они пройдут penetration-тестирование, которое проводится ближе к релизу новой версии. Поскольку головной офис заказчика и тестовая среда находятся в Москве, а наша команда — в Петербурге, то первый год разработки мы работали практически «вслепую». Настоящим спасением стали наличие WSDL и инструмент под названием SoapUI.
Он позволил нам быстро взвести mock-версию сервисов, отдающую тестовые данные, и разрабатывать, а в дальнейшем и тестировать приложение с помощью него. Такое решение, хоть и далеко от идеального, позволяет отловить в приложении большую часть ошибок, связанных с веб-сервисами.
Более того, поддержка скриптинга позволяет реализовать в заглушках какую-то несложную бизнес-логику. Например, выбирать разные ответы в зависимости от правильности логина и пароля в запросе.
Почти через год после начала проекта банк прокинул VPN в тестовую сеть из одного из Петербургских отделений, и разработчики с тестировщиками смогли тестировать и отлаживать продукт на реальных веб-сервисах.
Формы операций
Отдельная большая задача в такого рода приложениях — реализация и дальнейшая поддержка различных форм оплаты с многочисленными типами полей, поддерживающих различные способы валидации, отображение комментариев и ошибок, загрузку данных из шаблонов и журнала операций. Кроме того, формы для раздела «оплата услуг» реализованы динамическими, т.е. набор полей для них не вшит в приложение, а составляется «на лету» на основе запросов, приходящих с сервера.
Поскольку «Оплата услуг» была одним из первых видов активных операций в приложении, то с самого начала мы разработали некий внутренний фреймворк для работы с формами, позволяющий строить экранное представление формы из набора объектов, описывающих информацию о полях. Это дало хороший задел для дальнейшей разработки более сложных, но уже статичных (т.е. имеющих заранее известную структуру) форм.
HTML
Изначально было решено некоторые разделы приложения реализовать в виде HTML-страниц во встроенном браузере, в частности «калькуляторы» и «курсы валют». Это связано с тем, что они имеют довольно сложную логику, уже реализованную в JS на сайте банка, а реализация и поддержка нативного варианта займёт неоправданно много усилий, с учётом частоты их использования типичным пользователем.
Несмотря на кажущуюся простоту, для того, чтобы достичь максимально приближенного к нативному ощущения, этот способ требует довольно грамотной работы верстальщика, а также ряда хаков и костылей с нативной стороны.
Безопасность
Безопасность мобильных приложений — довольно горячая тема, однако, в грамотно спроектированном клиент-серверном решении большая часть заботы о безопасности ложится на плечи серверной команды.
Перед выпуском новой версии проводится полноценный аудит безопасности как клиентского, так и серверного кода, однако, до сих пор серьёзных замечаний к приложению не было. Естественно, вся команда должна знать и блюсти соответствующий топ от OWASP, однако, в нашем случае, на клиентской стороне есть не так много потенциальных уязвимостей, которые требуют пристального внимания. Основные уязвимые направления это:
- M2: Insecure Data Storage, выражающийся обычно в кешировании того, чего не надо, и логировании лишней информации, в частности, сетевого трафика (решается применением библиотеки логинга с настройкой уровней логирования; в нашем случае это CocoaLumberjack).
- M3: Insufficient Transport Layer Protection, выражающийся, например, в том, что выключенную на стейжинге проверку соответствия сертификата домену забыли включить для релизной сборки.
- M9: Improper Session Handling, для защиты от которого хорошо бы инвалидировать сессию после смены IP разумного периода неактивности либо просто по истечении какого-то времени.
Остальные риски к нам либо оказались слабо применимы, либо касались серверной стороны.
Заключение
Одна из самых сложных и недооценённых вещей в аутсорс-разработке — построение взаимоотношений с командой заказчика и отношение к приложению как к своему собственному продукту, а не к обычной продаже часов разработчиков. Мне кажется, с этой задачей мы действительно справились. С самой первой версии мы получали и читали пользовательский фидбек, переживали, если у пользователей что-то шло не так, торопились скорее всё исправить и с гордостью показывали коллегам результаты работы. Мы очень тесно сработались с командой Райффайзенбанка и без этого, я уверен, мы никогда бы не смогли достичь того результата, который есть сегодня.
Мы будем благодарны за ваш пользовательский фидбэк, который вы можете оставить в виде комментариев ниже либо на странице описания проекта.
Автор: krokhmalyuk