Одно приложение для трех платформ



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

    Вначале было слово


    Изначально наше мобильное приложение задумывалось как простой вспомогательный инструмент для учеников школы. Большинство уроков содержат некоторый набор лексики для заучивания, к нему и студент, и преподаватель могут добавлять слова прямо во время занятия, и все это по идее надо выучить к следующему классу. Понятно, что делать это на телефоне или планшете – удобно. Так появилась первая версия приложения для iOS, доступная нашим ученикам, содержавшая лишь четыре простых механики заучивания (словарная карточка, «помню — не помню» и две проверки с выбором правильного ответа из четырех вариантов). Никаких «умных» алгоритмов там не было, была простая зубрежка, а программа решала, что слово выучено, когда ученик определенное количество раз подряд правильно выбирал перевод. Позже такое же приложение было написано с нуля для Android.

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

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

    Но вот идея писать с нуля еще две версии приложения (для iOS и Android), а потом поддерживать и развивать параллельно все три, нам совсем не нравилась. Поэтому было решено ядро оформить в виде C++ библиотеки, единой для всех версий приложения, и дальше работать с ней.

    Поэтому мы, по сути, еще раз переписали все с нуля. Но один и, надеемся, последний раз.

    Одна библиотека


    Почему именно C++? Потому что С++ – кроссплатформенный язык, он отлично компилируется под iOS, хорошо поддерживается на Android, его можно использовать с PHP в вебе, скомпилировав C++ код в PHP-extension. Другие языки не могут похвастать такой поддержкой. Например, в случае выбора Java нам было бы проще сделать приложение для Android, но для переноса на iOS пришлось бы использовать непопулярные инструменты (jvm вроде RoboVM), а работало бы оно заметно хуже. Плюс более сложная, чем в случае C++, интеграция Java с PHP.

    В итоге у нас получилась такая картина: интерфейсы (клиентские программы), написанные отдельно для каждой платформы на их нативных языках (Objective C, Java и бэкенд на PHP), обращаются к общему для всех версий ядру приложения (библиотеке C++), выполняющему основную работу. Приложение также имеет связь с сервером (авторизация, хранение общих ресурсов, каталог статических сетов, словарь, потенциальная связь со сторонними приложениями) и хранилищем локальных данных (Realm).

    Таким образом, портирование на iOS оказалось самой простой и тривиальной задачей благодаря хорошей совместимости Objective C и C++. Все встраивается без проблем, работает очень быстро, это удобная платформа для отладки нового функционала.

    С Android ситуация чуть хуже, поскольку там приходится взаимодействовать с виртуальной Java-машиной, что влияет на скорость работы: низка скорость передачи данных между библиотекой и приложением. Но для наших нужд это не критично.

    Для веб-версии используется фреймворк PHP-CPP. Выбор был обусловлен удобством, наличием более-менее полной документации и поддержкой именно C++, а не C. К минусам относим проблемы с отладкой: смотреть логи – не самый удобный способ, а других официальный сайт не предлагает.

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

    И мы видим, что это хорошо!

    Посмотреть, как это работает, можно, загрузив мобильное приложение Aword для iOS или для Android. Веб-версия будет доступна позже.

    Напоминаем, что у нас по-прежнему много хорошей и интересной работы для талантливых специалистов.
    Skyeng
    Крутейшая edtech-команда страны. Удаленная работа

    Comments 16

      0
      Интересная статья. Как осуществляется сетевые запросы? используя нативные механизмы(NSURLSession) или механизмы c++
        0
        Ядро на C++ отвечает только за логику. Работа с базой данных, сетевые запросы и UI реализованы нативно.
          0
          А почему бы не использовать SQLite и libcurl? Тогда ещё большую часть логики можно будет вынести в C++.
            0
            Не рассматривали. Но думаю что использовать бы не стали, опять же, по историческим причинам. Мы имели 2 готовых приложения, в которые нужно было вставить большой кусок логики.
              0
              Возможно, что libcurl умеет делать не всё то, что умеет нативный NSURLSession.
          +4
          если пишите на C++, то что мешает использовать QtQuick из Qt?
            0
            Выбор нативной реализации UI был для нас легким решением по историческим причинам. Т.е. приложения были написаны на момент выбора инструментов реализации данной задачи.
            +1
            Я так понимаю ASP.NET, WCF, Xamarin не в почете?
              +2
              Они бы не встроили его в нативное приложение.
                0
                использование нативного приложения, является обязательным условием? Я не пытаюсь навязать свое мнение, мне интересно причины именно такого решения, т.к. в дальнейшем мне надо будет решать подобную задачу проектирования, а приведенный автором статьи аргумент меня не склонил к использованию библиотеки c++.
                  0
                  Для нас это было обязательным условием. Если же приложения разрабатываются с нуля, возможно этот подход не для вас. К основным плюсам такого подхода я бы отнес производительность и безболезненную интеграцию в существующие нативные приложения. Если эти пункты для вас не критичны, возможно стоит посмотреть в сторону react native или чего-нибудь подобного.
                  0

                  Судя по статье они и не встраивали, а написали все с нуля:


                  Поэтому мы, по сути, еще раз переписали все с нуля.
                    0
                    Ну а в комментариях они пишут другое.

                    Если я правильно их понял, они переписали с нуля общий блок логики, и встроили его в существующие мобильные приложения.
                +1

                Возможно, вам будет интересно посмотреть на https://github.com/dropbox/djinni.

                  0
                  Спасибо за комментарий, в статье эта тулза не упомянута.
                  –1
                  WebView и AppCache ещё не изобрели

                  Only users with full accounts can post comments. Log in, please.