YDC — Pizza Powered iOS – Telegram
YDC — Pizza Powered iOS
242 subscribers
65 photos
95 links
Young Da Code 👨‍💻
Первый командный дайджест о мобильной разработке 🍕
Download Telegram
🏗 Немного не про SUI: хочется поделиться опытом из Satisfactory – и почему это очень похоже на мобильную разработку 😁

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

Для тех, кто не играл: Satisfactory – это про автоматизацию, конвейеры, производство и логику.
По сути – огромный симулятор архитектуры и процессов.

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

🔧 Этап 1 – Один конвейер, который делает всё
В начале строишь одну гигантскую линию: добыча → переплавка → крафт → сборка.
Работает, но к любому изменению очень чувствителен.
Как приложение, где одна ViewModel делает всё сразу – от сети до бизнес-логики.

🏭 Этап 2 – Отдельные заводы
Понимаешь, что так жить нельзя, и разбиваешь всё на модули:
болты отдельно, провода отдельно, пластины отдельно.
Это уже знакомо – модули, SRP, нормальная архитектура.
Удобно расширять, легче отладить.

📦 Этап 3 – Чертежи
Когда появляются чертежи – игра меняется.
Сделал чёткий работающий блок → сохраняешь → используешь повторно.
Прям как переиспользование компонентов в проекте.
Меньше ошибок, меньше копипаста, быстрее разворачивать новое.

🤝 Игра с продактом
Мы с PM подходим к игре так же, как к проекту:

- Я: «Давай оптимизируем поток, проверим эффективность, подумаем о масштабировании»

- Он: «Давай построим, запустим и посмотрим, что будет»

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

Перед строительством нового «модуля фабрики» мы реально обсуждаем – что нужно, как будет взаимодействовать с остальными цепочками.
А после запуска – устраиваем мини-ретро: где узкое место, что можно улучшить, что оказалось лишним.

Полноценная айтишная разработка, только в 3D и на другой планете.

🔄 Этап 4 – Рефакторинг
Через время база превращается в хаос, и ты перестраиваешь всё...
Выравниваешь уровни, перекладываешь конвейеры, чистишь старые решения.
Обычный рефакторинг проекта, который необходим чтобы потом можно было работать дальше.

⚙️ Этап 5 – Масштабирование
Когда порядок наведён, начинается настоящее удовольствие:
всё строится по понятным шаблонам, процессы предсказуемы.
Почти как проект с хорошей архитектурой: он не сопротивляется, а помогает.

🍕 Итог
Satisfactory удивительно точно отражает процессы мобильной разработки:
модули, автоматизация, рефакторинг, масштабирование, разные роли и разные взгляды на приоритеты.
Игра показывает, что хороший «поток» – это не про скорость, а про правильную систему.

🎮 Почему стоит попробовать 😏
Если вы пишите код, Satisfactory – отличный способ
почувствовать архитектуру руками.
Игра учит думать наперёд, проектировать модули, оптимизировать процессы и видеть узкие места там, где их не ожидаешь.

Советую попробовать: игра неожиданно хорошо прокачивает инженерное мышление

#R #модульность #архитектура

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
115
🤔 "Почему одни большие проекты стагнируют, а другие живут годами"?
Полный ответ дать сложно, причин очень много и, что еще сложнее, у них разная природа

🤔 Сегодня в своем feedly мне на глаза попался крутой заголовок на Medium, но вот её содержание меня не удовлетворило. На мой вгляд надо сместить акценты

🚬 Чтобы не клепать лонгрид накинул "обзорные" карточки только на технические и около-технические моменты, все для разработчиков 👌

📎 Managing Large-Scale iOS Projects...

#M #iOS #TeamWork #Architecture #Modularization

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
3221
🤫 Что общего у UITableView и git diff

Когда-то давно, лет 10 назад, у меня была задача: получать пачку данных с сервера, находить различия с кэшем и красиво обновлять UITableView, чтобы не было резких reload'ов, а всё плавно вставлялось, удалялось и двигалось.
Тогда задача обошлась мне, не в один день анализа и проектирования, чтобы научиться сравнивать старый и новый массивы.

Тогда ещё не было никакого CollectionDifference, и я просто пошёл реализовывать алгоритм Вагнера–Фишера и работать с вычислением: расстояния Левенштейна и редакционноого предписания - минимального количества действий и их последовательности чтобы из "ABC" получилось "ACD".

Ну и конечно, всё это руками прикручивалось к performBatchUpdates:


tableView.performBatchUpdates {
tableView.deleteRows(at: ...)
tableView.insertRows(at: ...)
}


Весело? Не очень. Но тогда по-другому никак.


Потом, с приходом iOS 13 и Swift 5.1, всё изменилось.
Apple выкатили DiffableDataSource, и вместе с ним — CollectionDifference.
Это была буквально революция, теперь можно просто сформировать снапшот и отдать его таблице:


var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems(items)
dataSource.apply(snapshot, animatingDifferences: true)


UITableView сама всё поймёт, сама вычислит, что вставить, что удалить, что переместить — и сделает это с анимацией.
А мы — просто передаём новое состояние.

Если копнуть глубже, то под капотом лежит алгоритм Майерса.
Он также находит минимальную последовательность изменений между двумя массивами.

Apple реализует его для CollectionDifference.
Можно глянуть исходники Swift или вот обьяснение алгоритма.

Но если хочется больше контроля или скорости — есть и альтернативы.
Например, DifferenceKit, который использует алгоритм Пола Хекеля.
Вот сам код.
Он быстрее в ряде кейсов, особенно если много данных, на это влияет сложность O(n), бенчмарки можно посмотреть на gh.
И с ним сделали даже backport - DiffableDataSource для старых iOS.

Мораль истории: задача сравнения последовательностей — стара как мир.
Её решают в UI, в git, в текстовых редакторах.
А теперь и мы — наконец-то — можем делать это в UITableView, не теряя нервы на написание сложных алгоритмов и работу с indexPath-ами.

#L #UITableView #DiffableDataSource #CollectionDifference #LevenshteinDistance

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
14222
🤔 Недавно после чтения статьи по коллекциям, обсуждали с коллегами, какие структуры данных мы реально используем в iOS — те, что есть «из коробки» в Swift/ObjC, те, что приезжают из Swift Collections, и те, что иногда приходится реализовывать самому.

👉 Подумалось мне что это отличная тема для серии постов.


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

План серии:
- Array-like структуры — contiguous/circular buffer, Copy-On-Write, NSPointerArray, BitArray, OrderedArray.
- Set-семейство — HashSet, BitSet, NSSet, NSOrderedSet, CountedSet их особенности и коллизии.
- Dictionary-семейство — HashMap, OrderedDictionary, NSMapTable, NSDictionary, LRUCache, NSCache.
- aka Navigation-структуры (рабочее название) — LinkedList, Stack, Queue, Deque, Heap.
- Приоритетные структуры — PriorityQueue, Min-Max-Heap.
- Деревья — BST, AVL, Red-Black, Splay.
- Графы — базовые реализации, обходы и тд.

А сегодня — первая подборка карточек: Array и всё “семейство” вокруг него.

#L #DataStructures #Swift #Collections

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
127
🤫 Debug-only SDK в iOS

Частая задача — подключить SDK только в Debug, но не тянуть его в Release:
дебажные тулзы вроде Flex, sandbox-SDK и прочее.
И вот как разные инструменты с этим справляются 👇

🍫 CocoaPods — старичок, который решает задачу идеально:

pod 'SomeSDK', :configurations => ['Debug']


И всё — магия происходит автоматически.

CocoaPods:
• генерирует разные .xcconfig под Debug и Release
• добавляет OTHER_LDFLAGS, FRAMEWORK_SEARCH_PATHS только в Debug
Это правильное поведение на уровне линковки.
И работает уже лет 10. Пруфы со времён 0.34.

🧰 Tuist — “сделай сам”:
Tuist ближе к Xcode, но отдельной поддержки Debug-only зависимостей нет. Официальный issue.
Что приходится делать:
• вручную писать xcconfig или BuildSettings и менять OTHER_LDFLAGS по конфигурации
или
• использовать ENV-ы при tuist generate
и
• создавать отдельные targets под Debug/Release
То есть руками воспроизводить то, что CocoaPods делает автоматически.

📦 Swift Package Manager — примерно как Tuist:
Можно исключать код через макросы #if DEBUG.
Вижу что можно колдовать с LinkerSetting-ами руками и использовать unsafeFlags с condition.
Но, что-то исследование через гугление, не дает статей по использованию.
Интересно почему? Все еще так мало адептов?
Сами мы spm в enterprise не используем, только периодически присматриваемся, и постоянно что-то отталкивает.
Поэтому буду рад, если скорректируете.

#L #Cocoapods #Tuist #SPM

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
43
😏 Полезные SwiftUI-компоненты.
На медиуме довольно много статей про «скрытые SwiftUI компоненты». Я как раз прочитал несколько, где автор рассказывает про полезные компоненты, о которых многие не знают.

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

⏱️ TimelineView – обновления по расписанию
Этот компонент автоматически перерисовывает View каждую секунду, минуту или по вашему интервалу.

Где нужен:
- часы
- таймеры и обратные отсчёты
- виджеты
- данные, которые должны обновляться «в фоне»

Почему лучше старых решений:
Timer → утечки, ручной поток, лишняя логика
Combine.Timer → громоздко
✔️ TimelineView → нативно, оптимизировано, просто

Плюс еще одно важное преимущество:
В режиме .animation TimelineView ведёт себя похоже на CADisplayLink: обновления идут в такт рендеринга, но без ручного управления runloop’ом и без риска забыть invalidate().
А в режиме .periodic система сама оптимизирует частоту, что экономит энергию.

Пример:
TimelineView(.periodic(from: .now, by: 1)) { context in
Text(Date.now.formatted())
}


🎛 PhaseAnimator – сложные анимации без таймеров
PhaseAnimator позволяет задать список значений (фаз), а SwiftUI сам плавно будет бегать между ними.

Когда использовать:
- shimmer и skeleton
- пульсирующие элементы
- бесконечные анимации

Почему лучше старых подходов:
раньше: onAppear + стейты + таймеры
✔️ сейчас: декларативно, чисто, предсказуемо

Пример:
PhaseAnimator([1, 1.3, 1]) { phase in
Circle().scaleEffect(phase)
}


🎨 Canvas – когда нужен кастомный рендеринг
Если стандартные формы SwiftUI уже не помогают – Canvas позволяет рисовать что угодно, как в CoreGraphics, но нативно в SwiftUI.

Где полезно:
- графики
- диаграммы
- сложные анимации
- частицы
- декоративные фоны

Почему лучше старых решений:
UIViewRepresentable + CoreGraphics → сложно, неудобно
✔️ Canvas → рисуешь прямо в SwiftUI

Пример:
Canvas { context, size in
context.fill(
Path(ellipseIn: CGRect(origin: .zero, size: size)),
with: .color(.orange)
)
}
.frame(width: 120, height: 120)


🍕 Итог:

Три компонента закрывают три разные задачи:

- TimelineView – всё, что зависит от времени
- PhaseAnimator – анимации с логикой фаз
- Canvas – кастомная графика без UIView

Это инструменты, которые позволяют писать SwiftUI-код быстрее и чище – и избавляют от костылей, к которым мы привыкли.

#R #SwiftUI

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
311