iOS Makes Me Hate
3.98K subscribers
1.15K photos
169 videos
15 files
1.33K links
Авторский канал про iOS разработку. Путь продуктовых самураев в MAANG.

Самое больше iOS сообщество практиков: https://boosty.to/lionbond/

Автор: @lvbond Senior iOS Yandex, ex-Avito, VK
Download Telegram
Wake the fuck up, Samurai
148
В it нет «правильных» или «неправильных» законов и правил

Следующий месяц мы продолжим погружаться в непростые и практичные вещи в SwiftUI, поэтому обещаного традиционного голосования с темой на месяц не будет. Демократия закончилась 🥲

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

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

🌟контекст имеет значение

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

🌟нет серебряных пуль

У каждых решений есть свои недостатки и плюсы.

🌟субъективные предпочтения

Многие решения зависят от личных предпочтений и опыта команды. Важно осознавать эту субъективность и избегать навязывания своих предпочтений как единственно верны

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

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

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

Принятие этой идеи способствует профессиональному росту и более эффективной работе в команде.
Please open Telegram to view this post
VIEW IN TELEGRAM
11
Кодстайл в крупномасштабном проекте на примере SwiftUI

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

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

Статья подчеркивает важность командной работы и согласованности в больших проектах. Хорошо продуманное руководство по стилю кода:
🌟Упрощает совместную работу.
🌟Облегчает обучение новых разработчиков.
🌟Повышает качество и стабильность продукта.

Здесь много очевидных вещей, но если ищите чеклист для вдохновения для своей команды, то отличный пример
Please open Telegram to view this post
VIEW IN TELEGRAM
8
SwiftUI Perfomance Tips

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

Это значит, что современному инженеру еще долго придется знать оба фреймворка.

Нашел статью с конспектом одной из самых полезных секций WWDC Demystify SwiftUI performance. Здесь собраны все важные советы, которые мы в будущем разберем подробнее:

🌟 уменьшайте количество данных, передаваемых в View, чтобы избежать ненужных обновлений. Используйте @Observable, чтобы отслеживать только нужные свойства.
🌟 избегайте тяжёлых вычислений в body, не злоупотребляйте AnyView, используйте _printChanges() для отладки.
🌟 обеспечьте стабильные id у элементов List и Table, и выносите фильтрацию/сортировку из View в вьюмодель .
Please open Telegram to view this post
VIEW IN TELEGRAM
14
⚔️ SwiftUI: Deep dive AttributeGraph p. 1

Вышла одна из самых больших и полезных статей в ноушене.

Продолжаем разбирать кишки SwiftUI. В прошлом посте мы очень поверхностно разобрали AttributeGraph. А также я сказал, что мне очень понравились ролики ребят из objc.io. Я купил подписку и решил сделать их разбор платного контента.

У них крутейший контент где целых 6 часов они пишут с нуля свой AttributeGraph и разбирают его потенциальную работу.

Я решил сократить время и разобрать в ноушене первые четыре главы из девяти. Получилась большая статья где они разбирают:
🟣Что такое AttributeGraph и зачем нужен
🟣Как он устроен изнутри: Node & Edges
🟣Псевдокод AttributeGraph изнутри и построение графа
🟣Правила и вычисления: механизм dirty/pending
🟣Перевычисления зависимостей

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

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

🧬 Получить доступ к разделу и другой контент можно 💰тут или ⭐️ тут
Please open Telegram to view this post
VIEW IN TELEGRAM
11
готовимся на праздниках записать мок-интервью по SwiftUI. Киньте хорошие задачи, которые задаете или вам давали на собесах, пожалуйста.

че там вообще спрашивают на рынке? рефакторинг, биндинги, кишки или лайфкодинг?
8
🚴‍♂️Как написание своих велосипедов помогает развитию

Помните мы читали одну из лучших книг прошлого года? The Software Engineer's Guidebook. Тогда я делился главой про написание кастомных решений. Автор говорил, что свои велосипеды — это лучший путь для карьерного и профессионального развития. Фундамент promotion driven development.

Утверждение крайне спорное. В комментах поста крутые инженеры немного поспорили выгодно ли писать свои решения или лучше заимствовать чужие?

Недавно заметил за собой, что в канале ни разу не писал разборы чужих опенсоурсов. Дико не люблю разборы чужих библиотек и фреймворков. Своих велосипедов на работах всегда хватало 😂

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

В FAANG’ах любят писать все свое. На то есть несколько причин:

1. Антипаттерн Vendor Lock. Используя закрытое чужое решение, становишься от него зависимым.

В Яндексе есть свой git, jira, свой teamcity. Казалось бы зачем? Помню, как у многих были проблемы с CI. А в Авито в один день отключили корпоративные учетки гугл доков, потеряв очень много ценной инфы.

Также самое и в мобилке. Если либа не обновлялась год, то значит она почти мертва. Стоит ли тащить избыточное решение целиком или лучше взять лучшую часть и адаптировать под себя?

2. Если твоя компания может позволить нанять себе лучших специалистов и у них есть все нужные ресурсы написать решения лучше, то почему этого не сделать? Так ты поможешь и продукту выполнить метрики. И создать технологичное конкурентное преимущество.

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

Слышал, что написать свой AVFoundation в ВК видео вроде заняло почти три года. Но объективно плеер ВК в разы лучше телеграмовского.

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

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

Мораль. Использовать готовые решения можно и иногда даже необходимо, но если у тебя есть ресурсы и возможности создать свое — то преступление этими возможностями не пользоваться.

Но все же иногда стоит помнить, что инженер оценивается не потому сколько прочитал, а сколько написал сам.
Please open Telegram to view this post
VIEW IN TELEGRAM
1022
Почему обучение это не лестница, а круг

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

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

Вчера я учился. Сегодня — менторю. Завтра опять учусь.

Когда перестаешь учиться — начинаешь отставать. Сначала ты ничего не знаешь, потом избыточно самоуверен.

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

Каждый новый уровень — не про «знаю всё», а про «теперь знаю, как мало знаю».

Ты растёшь — когда снова чувствуешь себя джуном
184
SwiftUI: Основы Dependency Injection

Мы уже достаточно поговорили про layout engine SwiftUI: узнали что такое wrapper'ы, view & render trees, для чего нужен AttributeGraph и другие вещи. Пока сделаем паузу в UI и множно сказать что для основы работы этого достаточно.

Ведь кроме UI есть еще и другие слои: роутинг, диплинки, пуши, сеть, тесты, модуляризация, данные и многое другое. Кнопки красить мы плюс/минус научились, осталось еще 80% работы 😂

Одними же кнопками дело не ограничивается — мы только начали. Все выше нельзя сделать хорошо без опыта в построении архитектуры. А начиная большую тему нельзя не начать с DI.

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

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

В книге "Mobile System Design" есть отличный блок глав для чего нужен DI:
- Нужно передавать компоненты, которые используются в нескольких местах (например, логгером, аналитикой и тп)
- Хочется быстро переключать окружение: staging, прод, тест.

Dependency Injection — это как если бы ты не сам ходил за продуктами, а тебе их приносили на кухню. Всё нужное приходит извне, а ты просто готовишь — удобно, гибко и легко менять ингредиенты.


Это просто: мы передаём нужные объекты туда, где они нужны. Никакой магии. Просто значения, которые идут по цепочке.

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

Даже если мы обожаем third-party решения я считаю нельзя недооценивать силу простого и скучного кода.

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

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

В следующих постах аккуратно будем погружаться в DI: от самого простого до чуть более продвинутого.
Please open Telegram to view this post
VIEW IN TELEGRAM
12
⭐️ Подписки на Tribute

Многие встречаются с проблемой сервиса бусти: не проходит/продлевается оплата; разные цены в разных регионах 🤯 и другие приколы.

Поэтому делаю отдельный пост для истории со всеми подписками трибьюта. Там в целом удобнее и для вас дешевле.

🌟 Подписка мидл
🌟 Подписка мидл+
🌟 Годовая подписка на все виды контента
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🌟 SwiftUI: Composition Root DI

Два главных заблуждения начинающих разрабов:
- Достаточно выучить только SwiftUI и можно будет сделать любое приложение на нем
- Изучение SwiftUI это изучение только UI компонентов и API фреймворка

Но старые концепции и принципы требуют адаптации для SwiftUI тоже.

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

Лучший блог для архитектур уже разобрал множество крутых идей для дизайна приложений на SwiftUI. Одна из них Composition Root.

Composition Root — это центральное место в приложении, где создаются и связываются все зависимости. По сути это очень простая концепция. Вместо того чтобы компоненты (например, ViewModel) напрямую создавали свои зависимости, они получают их извне, обычно через инициализатор.

В отличие от Service Locator или Singleton он помогает явно распределять зависимости в точке входа приложения, где они явно создаются в одном месте (SceneDelegate, @main, App). А также использует Dependency Injection через init injection.

Все это лучше помогает тестировать и масштабировать код.

🌟 В скриншотах упрощенный пример как использовать Composition Root в SwiftUI (там нет фабрики и assembly)
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
642
💎 Разработка приложения на SwiftUI: Почему нужен DI впервую очередь

SwiftUI по умолчанию делает многое автоматически — это удобно, но без DI ты быстро начнёшь жёстко связывать View, ViewModel, сервисы, хранилище, API и т.д.

А значит тестировать, переиспользовать, изменять, рефакторить код — страшно и больно

С DI легко заменяешь зависимости на моки:

let mock = MockUserService()
let vm = ProfileViewModel(userService: mock)


Чистое разделение ответственности c помощью DI помогает разделить на компоненты:
View — Отображение
ViewModel — Логика UI
Service — Данные/API

Гибкость для разных окружений:


#if DEBUG
let service = MockUserService()
#else
let service = RealUserService()
#endif


Лёгкий переход к модульной архитектуре

С DI ты можешь:
- выносить модули в отдельные фреймворки,
- управлять зависимостями централизованно,
- добавлять фичи, не ломая всё остальное.

В следущем посте разберем в чем главное отличие работы с DI в SwiftUI и UIKit
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
9