Сочетать учёбу и работу в IT – задача, мягко говоря, непростая. Даже если вы только ходите на занятия и делаете «домашку». А уж если вы захотите сами организовать обучение – сложности будут расти в геометрической прогрессии.

Недавно наша команда iOS-документов в МойОфис решила перейти на SwiftUI – декларативный UI-фреймворк от Apple. После достаточно безболезненного рефакторинга модуля с UIKit на SwiftUI оставалось всего ничего – обучить коллег новому фреймворку.

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


Привет! Меня зовут Коля Чаусов. Я разрабатываю iOS-Документы в компании МойОфис, и это нетехнический лонгрид о том, как в феврале 2024 года мы запустили трёхмесячное обучение SwiftUI для нашей команды.

С чего всё началось

Наша команда iOS-документов была сформирована практически с нуля в 2023 году. В неё вошли десять “айосеров”: несколько сеньоров с большим опытом продуктовой разработки на ObjC, ребята с опытом в Android-разработке, бывшие автоматизаторы тестирования, и ребята из студий заказной разработки. Также частью нашей команды стали две тестировщицы и два дизайнера с горящими, на тот далёкий от релиза момент, глазами.

К концу 2023 года мы подняли минимальный поддерживаемый таргет до iOS 15, Android-команда начала изучать Kotlin Multiplatform, а по техническому долгу накапали проценты и его пришлось оперативно возвращать.

Всё это привело к необходимости внедрения SwiftUI, взамен (пока не полностью) UIKit. Мы приняли это решение, потому что с 15 версии iOS SwiftUI получил необходимый минимум инструментов, который позволяет не спотыкаться на каждой задаче. Его декларативность и реактивность очень схожи с Compose на Android, что позволяет ещё больше сблизить платформы. Наследие ObjC+Xib хотелось рефакторить сразу на свежем стеке, а не переписывать дважды.

Зачем нам понадобился новый UI-фреймворк и чего хотел бизнес?

  1. Редизайн. В 2023 году наше приложение выглядело на фоне конкурентов немного устаревшим, и с этим нужно было что-то делать. Хотелось свежести и лаконичности.

  2. Техдолг. Наше iOS-приложение по уши в легаси имеет большое наследие. Раньше его разрабатывали две команды: одна писала для iPhone, а другая для iPad, что сказывалось на качестве. Для вёрстки использовались разные подходы, сочетание Xib+ObjC отпугивало самых опытных сеньоров. Хотелось однообразия и простоты.

  3. Перспективы мультиплатформенной разработки. Один из модулей приложения мы начали переписывать на Kotlin Multiplatform. Эта технология выделяет общий логический модуль написанный на Kotlin, к которому и со стороны Android и со стороны iOS рисуется нативный UI. Первые наброски модуля были сделаны на UIKit, и чувствовалась тяжесть подвязки компонентов, особенно в сравнении с Compose у коллег. Хотелось большей схожести между платформами.

  4. Поднятие минимальной поддерживаемой версии iOS. Бизнес позволил нам поднять таргет до iOS 15. Это разблокировало много плюшек, в частности дорогу к уже более-менее окрепшему SwiftUI. Хотелось новых технологий.

  5. Скорый релиз. Бизнес хотел выпустить редизайн как можно раньше, поэтому нужен был простой и удобный инструмент вёрстки. iOS-коммьюнити может не согласиться, что SwiftUI прост и удобен, однако практика показала, что скорость создания компонентов на нём примерно в два раза выше чем на UIKit. Хотелось успеть в срок.

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

В итоге мы попробовали переписать iOS-архитектуру KMP модуля под SwiftUI, обновили экраны с UIKit на SwiftUI и результат нас устроил. У нас получилось создать удобную библиотеку компонентов, быстро нагнать то, что уже было сделано на Android. Фреймворк нам понравился и мы решили попробовать его в продакшене.

Осталось только научить команду с ним работать. Ниже расскажу, как, методом проб и ошибок, мы выстроили обучение в команде.

Первая проблема

Оказалось, что задумать — это одно, а интересно и классно воплотить – совсем другое. Нашей первой проблемой стал план обучения.

Мы созвонились с тимлидом и ментором и наметили программу учёбы. Договорились, что каждый член команды подготовит отдельную тему и расскажет о ней. Так докладчик лучше разберётся в теме, а команда получит больше полезного материала. Осталось самое сложное – написать и рассказать программу. До первого занятия оставалась неделя.

За два дня до начала учёбы я поймал себя на том, что конспектирую англоязычную дипломную работу про сравнение производительности UIKit и SwiftUI. Я понял – слушать это в аудитории было бы неинтересно даже мне.

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

Вторая проблема

Ещё одной проблемой, проявившейся уже в процессе обучения, стало то, что учебные задачи были плохо связаны с реальными тасками. А отдельного времени на решение выделено не было. Конечно, никто бы не набросился на тебя с критикой, что ты сидишь над учебным заданием, вместо актуальной работы. Но особого желания бросать задачи из прода не было. Часто всё рабочее откладывалось на вечер, в духе “Домой приеду и там порешаю спокойненько”. Но, увы, решать задачи с PS5 не очень получается.

Принципы обучения

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

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

  • На занятия нужно время. Недостаточно сказать "Вот материалы, тут примерно на пару часов в неделю, читайте в свободное время". Мы выбрали день, когда все в офисе (мы работаем по гибриду 2/3), нашли один из свободных временных слотов и забили его у всей команды в календаре, попутно забронировав удобную переговорку с проектором на следующие 3 месяца.

  • Максимум практики. Огромное количество теории можно спокойно найти на YouTube, WWDC и в куче статей, которые первыми выдаёт по теме поисковик. А вот практика оттачивается только через перезапуск Xcode кодинг.

  • Минимум домашки. Признаюсь, я просто ненавижу домашку редко делаю дополнительные задания. Всегда найдётся важная тасочка, интересная статья или к концу недели уже не останется сил. Также домашку тяжело регламентировать по времени и неудобно проверять. А самое неприятное – она может отпугнуть от обучения. Помните гнетущее чувство на уроке, когда не подготовились, а вас могут вызвать к доске? Отличная причина прогулять этот злосчастный урок.

  • Применяй на практике. Кажется, что два предыдущих принципа противоречат друг другу – если нет домашки, как практиковаться? Выход есть – делать рабочие задачи. Гибкий подход к планированию и разработке позволил нам решать продуктовые задачи параллельно обучению. Мы были готовы к парному программированию и долгому код-ревью. Зато разработчик мог принести проблему из жизни на занятие, поделиться ей, и получить направление для решения.

Как проходили занятия

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

  • В начале занятия мы показываем задачу. Стартовый набор данных, требования к экрану и его дизайн. Почти все задачи–экраны уже были в приложении и нуждались в рефакторинге (ObjC+Xib).

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

  • Для продвинутых ребят мы  подготовили отдельные задачи – со звёздочкой, чтобы не скучали.

  • По необходимости мы наваливали базы показывали презентацию с сопроводительными материалами. За десять встреч мы делали это три раза: на вводном занятии, чтобы продемонстрировать с чем мы будем работать; когда разбирались с коллекциями и основными принципами фреймворка (условно Identifiable + Hashable); и когда изучали врапперы и архитектуры.

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

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

Во время обучения я дополнительно занимался пет-проектом, верстая UI на Сompose (Kotlin), который также является декларативным фреймворком. Знания SwiftUI легко легли и на использование Сompose. В сравнении со SwiftUI, Compose показался мне более гибким и вкупе с корутинами более законченным решением для вёрстки UI.

SwiftUI показался мне достаточно перспективным фреймворком, с его помощью можно легко разрабатывать несложные представления, но для iOS 15, на мой взгляд, он сыроват. В дальнейшей разработке я собираюсь внедрять SwiftUI. Особенно полезным он может быть для прототипирования интерфейса.

Волков Андрей, разработчик iOS-документов

К чему мы пришли и какие задачи закрыли

  1. Редизайн. Теперь мы активно пилим компоненты на SwiftUI, а дизайнеры стали лучше понимать как ведут себя компоненты.

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

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

  4. iOS 15. Мы почти не использовали UIKit-компоненты (пришлось обернуть только UITextView и контроллеры для навигации) и планируем отказаться от них в будущем.

  5. Скорый релиз. Сроки не поджимают, мы всё успеваем.

  6. Формирование единого подхода в команде. Из 10 человек 6-7 активно пишут на SwiftUI, платформенная команда подключается к код-ревью. Мы наработали новый стайл-гайд и код-стиль для SwiftUI. Особенно полезным было придерживаться код-стиля на занятиях, правила быстро автоматизировались.

А дополнительные плюшки?

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

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

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

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

У меня остались очень хорошие впечатления от обучения SwiftUI. Как лид команды, хочу отметить следующее:

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

  • такие мероприятия помогают еще больше сплотиться команде для достижения общей цели.

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

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

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

Артём Конарев, руководитель группы iOS-документов

В общем, команде понравился опыт, и мы уже планируем внутренние программы по Kotlin Multiplatform и Gradle.

Кстати, для меня стал открытием тот факт, что если вы хотите сами глубже изучить технологию – попробуйте обучить ей других. На уроках мы постоянно находили особенности и странности SwiftUI, которые потом подробно разбирали и смогли правильно применить на проекте.

И снова немного о проблемах

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

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

Следующая проблема – ставка на асинхронное обучение. По ощущениям, она либо не зашла, либо даст свои плоды сильно позже. Мы записывали каждую встречу, формировали страницу на Confluence с примерами кода, разъяснениями изменений и сложных мест. Этот процесс, хоть и не так сильно, как остальные, тоже жрёт время. Правда что-то мне подсказывает, что видеозаписи не смотрели ни разу, а текст читали хорошо если у 2-3 занятий. Остаётся надеяться, что материалы помогут в будущем при онбординге новичков.

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

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

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

  • Оказалось страшно учить коллег “как надо, а как не надо”. Одолевали сомнения – а вдруг ты всю жизнь что-то делал неправильно и сейчас испортишь жизнь ещё куче человек? А зачем иначе SwiftUI?

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

И что в итоге?

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

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

Для тимлидов/менеджеров:

  • Выделяйте время на подготовку. Ментору нужно готовить материалы, настроить репозиторий, выбирать и описывать задачи. Мы заводили отдельную таску на каждое занятие в общем спринте. По ощущениям она занимала 2-3 сторипоинта (при в среднем пяти сторипоинтах за двухнедельный спринт).

  • Выделяйте время на занятия. Если не забить календарик – туда точно упадут другие встречи.

  • Лучше очно. Если у вас есть подходящего размера переговорка и проектор – бронируйте.

Для менторов:

  • Не бойтесь пересматривать и перекраивать программу, если чувствуете что-то неладное. 

  • Если вам скучно её делать – другим будет скучно её проходить. Ищите способы заинтересовать учеников (лучше практики ничего не придумали).

  • Старайтесь двигаться от практики к теории. Скучающая аудитория, которая занимается своими делами – хуже, чем пустая.

  • Если вы чувствуете, что готовы стать ментором – обязательно сообщите лиду или менеджеру. Обещаю, будет сложно и страшно, но чертовски интересно!


Расскажите, как проводили обучение вы? Чем руководствовались? Как проходили занятия? А может, вы участвовали в похожем внутреннем обучении – тогда поделитесь, что вам больше всего понравилось, а что больше всего раздражало!

Комментарии (3)


  1. vvasilyev11
    15.08.2024 13:43
    +1

    Как дизайнер из команды Николая скажу, что хоть там было и много сложного в понимании для дизайнера, особенно когда дошло дело до архитектурных моментов, все равно это было очень полезно, как минимум пришло понимание и оcознание того, как строится UI-ная часть на SwiftUI и теперь иногда я сам могу залезть в Xcode и посмотреть как можно реализовать тот или иной компонент и как можно заюзать и модифицировать системные компоненты iOS. В целом, поверхностно я понял все, что преподавал Коля, спасибо за знания и опыт!


  1. Bardakan
    15.08.2024 13:43

    несколько сеньоров с большим опытом продуктовой разработки на ObjC

    сочетание Xib+ObjC отпугивало самых опытных сеньоров

    Здравствуйте. А какие у вас требования к iOS-сеньорам?


    1. Koliamba Автор
      15.08.2024 13:43

      Здравствуйте. Конечно, для нас всё ещё умение исправить UI-баги или немного изменить компонент в сториборде или ксибе – это одно из требований для сеньора. Но это требование продиктовано легаси и не совпадает с предпочтениями в команде