Мессенджер от майл. Два приёма для плавной работы приложения. Как мы делали приложение быстрым

Недели не прошло с момента презентации нового мессенджера ТамТам от Mail.ru Group, а в сети уже идут горячие обсуждения его достоинств и перспектив. Корреспондент ИА AmurMedia Евгений Никитенко в рамках рубрики DIGITAL разбирается, что же представляет собой новое приложение, пришедшее на смену "ОК сообщениям".

С самого старта проекта разработчики предупредили общественность о том, что ТамТам является переосмыслением "ОК сообщений" с навесами в виде дополнительного функционала. Недаром указанный ОК -мессенджер просто-напросто заменяется на ТамТам посредством обыкновенного обновления. Но давайте самостоятельно взглянем, чем же нас порадует новая программка, ведь, согласитесь, интересно, чем же пресыщенную современную аудиторию может удивить компания, уже владеющая такими мессенджерами, как ICQ и Mail.ru Агент, социальными сетями Одноклассники и ВКонтакте?

Честно говоря, мы немного колебались перед установкой TamTam на мобильное устройство, так как по предыдущему опыту прекрасно помнили, как нелегко бывает удалить продукцию Mail.ru Group с персонального компьютера, что уж говорить про смартфон - откатывать систему к заводским установкам не хотелось никому. В результате решено было установить программу на смартфон с ОС от Android, тем более, что ранее было заявлено "TamTam полностью бесплатен и не демонстрирует рекламные сообщения", а это дает надежду, что и дополнительных продуктов в комплекте не будет.

Что же, приступим, благо приложение доступно как для Android, так и для iOS. Стоит отметить, что меньше чем за неделю с момента старта приложения, с Play Market его уже успели скачать более 1 млн человек.

К слову, в отношении аккаунтов: ТамТам интегрирован с Одноклассниками, так что создавать новую "учетку" не нужно. В то же время, вы вполне можете завести аккаунт в ТамТаме без привязки к социальной сети, но это довольно спорный шаг, так как тем самым вы "обрубаете" значительную часть функционала и лишаете себя тех преимуществ, которые могут стать стимулом к выбору данного мессенджера. Авторизоваться, кстати, можно и через Google.

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



Мессенджер ТамТам. Фото: Евгений Никитенко, корр. ИА AmurMedia

Раз уж речь зашла о функционале — ТамТам позволяет переписываться в личных сообщениях, создавать групповые чаты, отправлять стикеры, "гифки", фото и аудио. Звонки ни видео, ни аудио, по крайней мере на данном этапе, совершить не удастся. Что, конечно, же не добавляет очков новичку на фоне уже действующих мобильных приложений. А вот каналы, к которым пользователей приучил другой молодой мессенджер Telegram — идея потенциально (особенно с учетом связки ТамТам-Одноклассники) довольно перспективная. Почему, объясним чуть позже.



Каналы в день старта мессенджера завели и некоторые звезды российского шоу-бизнеса, к примеру Полина Гагарина, на которую за это время успели подписаться почти девять сотен пользователей.



Каналы ТамТам. Фото: Евгений Никитенко, корр. ИА AmurMedia

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

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

Одноклассники



Набор стикеров в "Одноклассниках". Фото: Евгений Никитенко, корр. ИА AmurMedia

ТамТам



Набор стикеров в ТамТам. Фото: Евгений Никитенко, корр. ИА AmurMedia

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

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

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

Кстати, а как вы относитесь к новому мессенджеру от Mail.ru?

Каждый человек, создавший электронную почту на сервере mail.ru, может автоматически использовать мессенджер Mail.Ru Агент, точнее, его веб версию под названием «Веб Агент». Для работы с ним не требуется установка, ведь веб-версия этой простой в использовании программы с удобным интерфейсом доступна сразу при входе в почту.

Функционал

Доступны:

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

Достоинства и недостатки

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

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

Веб-версия поддерживает одновременное открытие четырех диалоговых окон и общение по отдельности с четырьмя людьми. Также имеется возможность создавать и общаться в групповых чатах.

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

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

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

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

Чтобы открыть Личный Кабинет, нужно открыть меню и перейти в «Настройки». Помимо возможности пополнить счет, здесь можно изменить настройки звонков, работать с тарифами и выполнять множество иных функций.

К сожалению, возможности совершать голосовые или видеозвонки недоступны в веб-версии мессенджера mail.ru Агент. Эта версия программы реализована для обмена пользователями текстовыми сообщениями и может быть использована в тех случаях, когда возможность установить полноценный клиент и пользоваться им отсутствует. Это может быть чужой компьютер или устройство с устаревшей версией ОС.

Системные требования

  • ОС: Windows 7, 8, 10

Как установить Mail.Ru Агент

Для использования онлайн-версии mail.ru Агента нет необходимости в установке десктопной версии приложения на компьютер. Программа работает через любой современный браузер, обновленный до последней версии - , и многие другие. Достаточно ввести логин и пароль в почте Mail.ru, выполнить вход в свой почтовый ящик и запустить Агент, кликнув на панель в правом нижнем углу.

Для других систем

, IT-компании

Mail.ru Group, в активах которой находятся мессенджеры «Агент» и ICQ, запускает новый продукт TamTam , сообщает «Коммерсантъ». Это приложение для обмена сообщениями, в которое интегрирована база из 290 миллионов пользователей, зарегистрированных в «Одноклассниках».

Новый мессенджер не был создан с нуля. Его авторы творчески переработали концепцию аналогичного приложения «ОК Сообщения», запущенного в июле 2016 года. По словам Владимира Кочеткова, автора и руководителя проекта TamTam, это позволило сделать новый продукт дешево и быстро. Разработку TamTam вели четыре месяца.

«ОК Сообщения» создавала команда разработчиков социальной сети «Одноклассники» (входит в холдинг Mail.ru Group). В феврале 2017 года мобильное приложение «ОК Сообщения» установили около миллиона владельцев смартфонов на платформе Android и более 300 тысяч обладателей мобильных устройств Apple. Теперь эти пользователи смогут заменить мессенджер на TamTam, установив специальное обновление от Mail.ru.

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

Сервис позволит переписываться в личных сообщениях и в групповых чатах, делиться стикерами с GIF-анимацией, отправлять фотографии, видео- и аудиозаписи. Мессенджер дает возможность общаться не только с друзьями, но и с подписчиками. В Mail.ru Group утверждают, что приложение должно стабильно работать и при слабом интернет-подключении. Оно уже доступно в App Store и Google Play.

TamTam будет интегрирован с другими проектами компании. В качестве успешного примера такой интеграции источник «Коммерсанта» приводит китайский мессенджер WeChat. Его аудитория приближается к 1 млрд человек. WeChat – одна из самых коммерчески успешных платформ. С его помощью в Китае пользователи могут, к примеру, записаться на прием к врачу, оплатить счета и заказать товары.

Кстати, у WeChat есть достойный конкурент – японский мессенджер Line. Оба мессенджера были запущены в Азии, где и имеют большую долю рынка. Безусловно в Японии и Корее, в домашних регионах Line, мессенджеру удалось закрепиться очень прочно, в том числе благодаря мощной рекламе и огромнейшем количестве товаров с брендом Line Friends.

Будущее TamTam будет зависеть от того, обретет ли он свое лицо, что будет отличать его от других мессенджеров. «Может, это и правильно - уйти от бренда ОК и сделать кроссплатформенный проект, который можно продвигать как через VK, так, например, и через почту Mail.ru», – рассуждает старший аналитик Sberbank CIB Светлана Суханова.

Аудитории «Одноклассников» и Viber существенно пересекаются, и если TamTam придется по душе пользователям «Одноклассников», то Viber может лишиться около 10-15% своей аудитории, отмечает управляющий портфелем Фонда развития интернет-инициатив Илья Королев.

На развитие третьего мессенджера Mail.Ru Group может повлиять новое законодательство. Вчера депутаты Госдумы внесли на рассмотрение законопроект о запрете анонимности пользователей мессенджеров. Идентификация пользователей сети должна осуществляться оператором связи с использованием абонентского номера, который есть в договоре об идентификации, заключаемого организатором обмена мгновенными сообщениями с оператором связи.

24 мая в Госдуму был внесен законопроект о необходимости введения штрафов за отказ от выполнения вышеуказанных положений. Для граждан сумма штрафа составляет 3-5 тысяч рублей, для должностных лиц - 30-50 тысяч рублей, юридических лиц - от 800 тысяч до 1 млн рублей.

Привет, Хабр! Меня зовут Юрий Буянов, я разработчик мессенджера TamTam. Сегодня я хочу рассказать вам немного о том, как он создавался и как устроен изнутри. TamTam - это новый мессенджер Mail.Ru Group, который был разработан на базе приложения «ОК Сообщения». В 2016 году мы сделали отдельный мессенджер в Одноклассниках для тех, кто часто переписывается в соцсети и кому удобнее это делать с помощью отдельного приложения.


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

Сложности, которые натолкнули на идеи

Начнём со сложностей: именно они принесли нам идеи, которые потом реализовались в продукте и в итоге превратились в преимущества приложения. Речь прежде всего о быстрой и стабильной работе мессенджера.


Стартовая аудитория TamTam - из самых разных уголков мира, в том числе с нерегулярным покрытием мобильной сети (а иногда и с полным отсутствием стационарного интернета). В некоторых странах СНГ за пределами крупных городов 2G-соединение - вообще фактически единственное окно в интернет.


Важно было и то, что далеко не все потенциальные пользователи TamTam каждый год бегут покупать новый айфон или ГОРЯЧУЮ НОВИНКУ от Samsung. По статистике, самый популярный девайс под iOS у наших пользователей - iPhone 5s, а под Android - недорогие Galaxy выпуска 2014-2015 годов. При этом у TamTam достаточно молодая аудитория: 28 % дневной аудитории - это люди в возрасте 27-34 лет, а более половины пользователей (54 %) - младше 35 лет.


Поэтому одним из приоритетных направлений в разработке мессенджера для нас с самого начала была оптимизация приложения с точки зрения как быстродействия , так и работы с сетью . Словом, требовалось незаметно для пользователей сделать так, чтобы приложение работало при любом уровне подключения. И при любом росте аудитории тоже. TamTam в первые же месяцы показывает неплохие цифры: число установок уже приближается к 3 миллионам, а число каналов уже больше 50 000.

Как мы делали приложение быстрым

Быстродействие с точки зрения пользователя - это в первую очередь скорость запуска. Время, которое проходит до отображения нового контента (например, при открытии чата с новым сообщением по push-уведомлению). Плавность работы в целом - в частности скролла. В iOS-команде мы стараемся тестировать и замерять быстродействие на iPhone 5 и iPhone 4S. Андроид-команда имеет в распоряжении Galaxy S3 и Мегафон логин за 1000 рублей. Как следствие, на более мощных девайсах приложение просто летает.


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



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


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


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


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


При выборе сторонних решений и библиотек в узких местах мы тоже старались учитывать быстродействие и компактность. В частности, именно поэтому мы выбрали MessagePack (причём для iOS специально делали бенчмарк разных реализаций), поменяли библиотеку для маппинга данных в объекты с Mantle на YYModel и остановились на lz4 в качестве алгоритма компрессии трафика.


Кроме того, для достижения плавности работы интерфейса мы симптоматически оптимизируем рендеринг:

  • избегаем offscreen-рендеринга, нагружающего процессор;
  • заранее в фоне ресайзим картинки вместо использования работающих в главном потоке стандартных UIViewContentMode;
  • делаем наши иерархии UI более «плоскими» и простыми;
  • кешируем те объекты и данные, создание которых слишком затратно. Начиная с высоты ячеек с текстом и заканчивая YYTextLayout (объект, который хранит информацию об отображении текста в библиотеке YYText), NSAttributedStrings и даже самими UIViews.

Во всех списках идёт ручная вёрстка без auto layout. Хотя auto layout мы тоже очень любим и используем декларативную вёрстку с помощью Masonry в коде - но только там, где это целесообразно.

Офлайн и работа при плохом интернете

При работе с сетью мы стараемся минимизировать трафик и задержки за счёт выбора быстрого компактного протокола и агрессивного кеширования.


В качестве способа общения с сервером мы используем только TCP-сокеты и бинарный протокол. Это позволяет нам как получать обновления с сервера в реальном времени, так и работать в более привычном режиме «запрос - ответ».


Сам API, т. е. набор команд поверх низкоуровневого протокола, можно в будущем при желании реализовать поверх другого транспорта, например на веб-сокетах. При всём этом нам не придётся трогать верхнеуровневую логику работы приложения.



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


В качестве формата для пэйлоада мы решили попробовать messagepack. Он не требует жёсткого задания схемы, очень компактный и имеет довольно шустрые библиотеки сериализации под множество платформ. По сути, это эффективный бинарный аналог JSON. Для того чтобы ещё более снизить потребление трафика, мы сжимаем пэйлоад алгоритмом lz4. Его мы также выбрали за скорость и небольшую нагрузку на CPU и батарейку.


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


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


С историей сообщений в чате всё чуть сложнее. Грузить заранее всю историю всех чатов бессмысленно, но что мы один раз получили - то мы кешируем и стараемся больше не запрашивать. Если посмотреть на то, какие участки истории чата закешированы, мы увидим, что в истории есть «разрывы». Например, с обновлением списка чатов после логина мы увидели, что последнее сообщение в чате изменилось. При этом у нас в БД есть участок (или несколько участков) истории чата, закешированный в ходе предыдущей сессии. Кроме того, мы не знаем, сколько сообщений есть на сервере между последним сообщением в чате и предыдущим закешированным сообщением, и это добавляет своих сложностей.


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


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


Задачи могут сохраняться в БД, они инкапсулируют в себя всю логику выполнения. Поскольку зависимости от других задач и от состояния приложения могут быть довольно сложными, то слежение за ними тоже реализовано в самих задачах. Например, задача отправки сообщения с фотографией должна убедиться в том, что фотография обработана, загружена на CDN (за это отвечают отдельные задачи), дождаться (при необходимости) сетевого подключения и только потом непосредственно попытаться отправить само сообщение.

Два приёма для плавной работы приложения

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


Одной из сложностей при разработке стал бесконечный скролл в чате, т. е. незаметная для пользователя подгрузка истории сообщений при прокрутке чата вверх. В 99 % случаев пользователь находится именно внизу чата и хочет проскроллить его вверх для того, чтобы прочитать старые сообщения. Здесь мы столкнулись с двумя проблемами.


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


Вторая проблема оказалась гораздо серьезнее: после вставки такой страницы в начало списка сообщений (сделанного на основе UITableView) contentOffset для уже загруженного участка сдвигается, и скролл «прыгает». Конечно, мы можем посчитать размер вставляемой страницы и изменить contentOffset обратно, но это приводит к резкой остановке анимации скролла, что некрасиво и обескураживает пользователя. Мы пытались делать это различными способами, включая такие, например, как отслеживание contentSize таблицы через KVO, но неизменно терпели неудачу: UITableView просто хронически не приспособлен к тому, чтобы элементы добавлялись в начало списка.


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


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


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


Вторая сложность, с которой мы столкнулись, - это анимированные и асинхронные обновления списков. Если несколько независимых обновлений происходят почти одновременно (например, подгружается страница истории вверху чата и приходит новое сообщение внизу), то данные, используемые делегатом tableView, могут измениться, даже если не закончилась анимация предыдущего обновления.


Это может привести к тому, что UITableView отрендерит неправильную ячейку или вообще упадёт: это ещё более вероятно, если вы используете предыдущий хак. Можно, конечно, обратиться к методу reloadData, синхронному в UITableView, однако это приводит к морганиям, остановке скролла и прочим раздражающим пользователя вещам.


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

Persistence

Для кеширования данных в iOS-клиенте мы используем библиотеку YapDatabase .


YapDatabase - это Key-Value хранилище поверх SQLite с очень большим набором возможностей. Мне эта библиотека кажется гораздо более простой и гибкой, чем CoreData. Здесь можно выбрать механизм сериализации объектов в базе: по умолчанию это NSCoding, а мы используем всё тот же MessagePack.


YapDatabase не требует наследования объектов от базового класса или реализации какого-то протокола, не привязывает объекты к контексту. Чтение и запись производятся с помощью синхронных или асинхронных транзакций.


А при помощи системы расширений доступны все те же возможности, что и в «настоящей» БД: произвольные SQL-запросы и индексирование нескольких полей, полнотекстовый поиск, подписка на изменения (как в NSFetchedResultsController), подключаемое шифрование, работа с CloudKit и т. д. Hello-world примеры работы с БД приводить здесь не буду, они есть в вики на github .


На мой вкус, YapDatabase повышает продуктивность и понятность кода, но некоторые мои коллеги её не очень любят. И их можно понять: после длительной работы с CoreData для перехода на YapDatabase нужно действительно несколько вывернуть мозг.


Кроме того, при асинхронной работе с базой через несколько соединений нужно хорошо понимать, как база обрабатывает параллельные запросы на чтение и запись: через одно или разные соединения . А ещё помнить, что объекты обновляются в БД целиком. Нельзя просто сохранить тот экземпляр, который вы прочитали какое-то время назад и модифицировали. Необходимо прочитать объект из базы, изменить его так, как вам нужно, и записать обратно в рамках одной транзакции. В противном случае можно случайно записать в БД устаревшие данные.


Вообще работа с базой очень удобно встраивается в наш реактивный стиль написания кода. Асинхронные шаблоны транзакций (чтение/запись/модификация отдельного объекта) очень просто завернуть, например, в сигналы ReactiveCocoa, и встраивать работу с базой в одну цепочку с отправкой и обработкой сетевых запросов.

Архитектура приложения

Много рассказывать про архитектуру не буду, но совсем не упомянуть о её законах жанра, как говорится, не позволяют. Докладов и статей про MVVM уже очень много (например, классический туториал в версии для Objective-C b RAC: часть 1 , часть 2 , или о реализации этого паттерна для Swift).


Под слоем ViewModels есть набор сервисов, который реализует (и по возможности инкапсулирует) бизнес-логику, логику работы с протоколом и кеширование. Навигация в приложении осуществляется с помощью так называемого роутера, т. е. объекта, инкапсулирующего код, необходимый для открытия того или иного экрана. На самом деле роутеров в процессе стало несколько, поскольку у роутера есть тенденция становиться эдаким очень жирным God Object. Поэтому там, где это возможно, мы стараемся его декомпозировать. Например, за весь процесс регистрации/аутентификации пользователя отвечает отдельный роутер.


По опыту предыдущих проектов мы знали, что Dependency Injection очень упрощает структуру приложения и здорово облегчает изменения в архитектуре. В самом начале мы использовали для DI фреймворк Typhoon , но в ходе оптимизации времени запуска приложения выяснили, что разрешение зависимостей занимает непозволительно долгое время на старте приложения (единицы секунд на слабых устройствах). Поэтому мы перешли на ручной DI через property-based injection. Не сказал бы, что кода стало больше: уровень сервисов в приложении обычно настраивается в одном классе, а вся конфигурация сервисов легко читается. Для share и imessage экстеншенов, естественно, сервисы конфигурируются отдельно, поскольку в этом случае нужен гораздо меньший их набор.


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

Добавить метки


Top