Под «капотом» Тайного Санты

Под конец 2016 года разработано приложение для Тайного Санты под iOS. На работе не первый год уже в него играем. А тут в сентябре бизнес заказчик в лице жены объявил — «Ты ж программист, а нам на работе надо в Тайного Санту сыграть — можешь написать приложение к Новому Году для нас?» И было принято решение запилить приложение.

download_on_the_app_store_badge_ru_135x40

Далее расскажу про подробности разработки и используемые технологии.

Требования

Был составлен примерный список требований:

  • Должно быть красиво
    • Анимация снега
  • В виду наличия форм для ввода данных
    • Валидация данных
    • Хранение данных
    • Отправка данных
  • Бизнес логика

О сроках

Они были оптимистично оценены в 1-2 месяца, а по факту в 4. Релиз был 20 декабря. Надо понимать, что это лишь в выходные пилилось. Где-то в выходные не получалось, где то писалось в будни дни. В совокупности получилось дней 20-25. Полный рабочий месяц. Можно прикинуть сколько стоила разработка приложения.

Структура навигации

Всего 8 View Controller’ов (Экранов), включая Navigation Controller.

  • Стартовая страница
    • Создание игры
      • Добавление организатора
    • Список игр
    • Конкретная игра
      • Добавление участника
      • Конечная страница

В первой реализации экран «Добавление организатора» и «Добавление участника» были объединены из-за почти идентичной визуальной составляющей, но потом были  разделены из-за бизнес логики и для более чистого кода.

Архитектура

«Луковая»(слоистая) архитектура приложения была применена вместе с MVVM.  В основном из-за желания попробовать binding для MVVM. Не такая тут сложная архитектура и требования, чтобы применять VIPER. Да и скорость разработки так же была важна — дедлайн в декабре.

Первые «подводные камни»

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

Отправка писем по электронной почте

Надо сказать это не тривиальная задача для iOS клиента, учитывая, что хотелось использовать системное API, а-ля java mail api. Но не тут то было, все что мы имеем на клиенте это — MFMailComposeViewController. Можешь отправить данные в другие приложение по созданию писем. Но это и не правильный подход, если учесть, что будет приложение не только под одну платформу. Нужен сервер.

Сервер отправки писем

Свой сервер поднимать под API отправки писем не хотелось. Найдены альтернативы:

  • SendGrid — платформа по маркетингу на основе отправки email
    • Есть бесплатный лимит — до 12000 писем в месяц
  • MailChimp — платформа по маркетингу на основе отправки email
    • Есть бесплатный лимит — до 12000 писем в месяц

Все они примерно одинаковые. Был выбран SendGrid.

Но не все так гладко — нет sdk под iOS. Как быть?

Zapier

Неожиданно открыл для себя этот сервис по интеграции между веб приложениями(api). Очень в тему подошло для отправки писем. Планировалось, что данные игры будут записываться в Firebase, это в свою очередь будет тригерить отправку электронных писем.

Firebase+Zapier+Sendgrid

Но не срослось. Последнии изменения в api Firebase не позволяют отслеживать запись в таблицы. Не успели еще изменить документацию. Пробовал, писал в техподдержку, исправили в документации.

Webhook+Zapier+Sendgrid

На выручку пришел встроенный в zapier сервис по генерации вебхуков, ака api. Генерируется адрес, на который ты отправляешь json. Zapier его видит, парсит и можно с этими данными уже интегрироваться в другой сервис. Что и было сделано с Sendgrid. Дальше дело техники:

  • Сформировать корректный формат для json Webhook’a
  • Создать шаблон для отправки писем для Sendgrid

Анимация снега

По задумке надо было создать sprite kit particle и интегрировать в VC. По факту даже ничего создавать не пришлось. Шаблон снега уже есть + еще 6 других шаблонов.

Осталось интегрировать в VC и настроить background. Вот тут что то я не нашел адекватной документации, все либо сразу игру делают, либо сразу. Не нашел ничего адекватного для применения, в духе raywanderlich про интеграцию во VC. Только создаем Sprite Kit Game. Пришлось методом проб и ошибок.

Итак все просто. Коренной View у VC делаем SKView в storyboard. Дальше уже в жизненном цикле создавать SKScene и интегрировать в self.view. Причем сцену останавливать не надо на viewWillDissapear. Сцена в свою очередь состоит из SKNode. Вот в в ноду уже анимация и добавляет. Бэкграунд кстати тоже туда в виде отдельной ноды.

Вот анимация у нас и готова. Сделаны нужные сабклассы для минимума кода и можно уже ко всем VC где требуется снег применять.

Валидация полей

Итак текстовые поля говорите и MVVМ. Binding с KVO замечательный. Apple так не считает и сделала UITextField не KVO совместимыми. Прилетела птица обламинго. Используйте делегаты. Такую идею похоронили, но очевидно же, что нужен биндинг для форм. Android даст фору в этом направлении в несколько шагов.

Ах да, у вас же ошибки есть после валидации. Где их показывать apple? В alertView? Горите вы со своим alertView и uitextfield. Фраза про андроид.

Лирическое отступление. Вот все говорят, что технологическое отставание продуктов apple связано с их более адекватной доработкой. Допиленность софта, оптимизация. Да, возможно так и есть, но по части софта и дизайна есть явные недоработки. Год назад мне показались стандартные, базовые элементы жутко устаревшими на фоне Material Design, а если взглянуть на их стандартные приложение вроде store, то мне аж не по себе. Они не менялись со времен первого iphone. Добавили blur? Vibration effect?  Я уже часто вижу floating button из MD, да чего уж там, я сам их хочу делать в приложениях. В плане дизайна приложений задает тон Android. И работы в этом направлении не видно. Swift говорите пилят? Новую MacOs? 3.5 мм выпиливают? Да вы б**ть выпилите свой старый дизайн сперва и xcode до ума доведите. Инноваторы хреновы.

Так вот где показать ошибку возле текстового поля? Есть несколько вариантов. Заморачиватся с ячейками меняющими размер не хотелось. Использовал библиотеку TextFieldValidator. Не самая свежая. С багами. Сделал pull-request. Вряд ли закоммитят в виду заброшенности. Бывает.

Ваши варианты валидации полей приветствуются в комментариях.

Хранение данных

Тут ничего особенного — Core Data + sqlite. Две сущности один-ко-многим. Игра и игроки. Все читал про MagicalRecord, мол уже не торт и не поддерживается в виду нововедений iOS 10. Вот решился попробовать. Шикарная вещь. Context и persistent store по «фен шую«. Крайне рекомендую к использованию.

Использовал Mogenerator для генерации NSManagedObject Subclass.

Отправка данных

NSUrlSession. В отдельной операции.

Составные операции

Не могу не затронуть эту тему. Это же просто прекрасно. Advanced Operations были показаны на WWDC 2015. Фактически Promise. У вас есть цепочка событий, атомарных. И каждое звено можно использовать в других цепочках. А то обычно начинают сабкласить NSOperations, они обрастают связями с другими операциями и потом уже не могут быть переиспользованы. SOLID во всей красе.

Надо отдать должное и сказать спасибо rambler и всем тем, кто разрабатывал COOperations.

Лирическое отступление. Посетив конференции гигантов отечественной и не очень IT индустрии по iOS. Яндекс, MailRu Group, Rambler&CO могу сделать небольшой обзор по подходу к организации кода и в целом поддержки проекта. Мнение чисто субъективное.

В Яндексе кто в лес, кто по дрова. Все зависит от команды. Кто то пишет тесты, кто то на них забивает. Кто-то не использует autolayout. Правят балом «эффективные менеджеры». Единобразия в подходах нет.

В мейлру прям такого как в яндексе заметить не удалось. Об этом не говорят. Они вообще мало говорят по iOS. В отличии от Android. Наработок по iOS в их гитхаб репозитории не найдено.

А вот рамблер приятно удивил. В отличии  от не самого «приятного» образа по своим сервисам по сравнению с тем же яндексом и mail. По части iOS разработки они на голову впереди конкурентов. Главное, что отделяет их от конкурентов — это выработанный кровью и потом промышленный подход к созданию софта для iOS. Единообразный среди всех проектов. В результате получились прекрасные наработки по VIPER, COOperations, Generamba. Я бы их по праву назвал законодателями разработки iOS и не только в России.

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

В итоге получилась цепочка операций по формированию запроса к webhook’у. Оттестированных.

Бизнес логика

Из примечательного только сам алгоритм перетасовки получателей.

Тасование Фишера–Йетса/Алгоритм Саттоло

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

Дальше просто по цепочке перебираем перетасованный массив. Все просто.

Можно усложнить 🙂 Но незачем.

Дизайн

Только на 3ей итерации зашел. Спасибо сестре 🙂 Контакты позже.

Вместо итога

Все только начинается 😉 Возможно придется переписать на VIPER. Но сперва Android версию.

С Наступающим Всех ! Чистого кода и стройной архитектуры в приложениях! Играйте в Тайного Санту!

Продолжение следует…

 

Добавить комментарий