Мобильный трудоголик
1.48K subscribers
66 photos
10 videos
304 links
Пишу простым языком об iOS разработке на Swift и мобильной разработке в целом.
Обо мне: https://t.iss.one/hardworkerIT/3
Чат: @hardworkerChatIT
Канал про разработку и жизнь в ИТ: @itDenisov
Вакансии по мобильной разработке: @mobileDevJobs
Download Telegram
🔢🏋️ Взгляд изнутри: как развивается рабочий проект Swift для Android.

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


Ядро и производительность - нативный подход:

Ключевой принцип: Swift компилируется напрямую в машинный код для процессоров Android, минуя виртуальные машины. Это не обертка или трансляция, а полноценный нативный бинарник. Такой подход ставит его в один ряд по производительности с решениями на C и C++, созданными через NDK, но с критически важным отличием - встроенной безопасностью памяти и современным, выразительным синтаксисом. Для работы на устройстве вместе со сборкой поставляется собственная среда выполнения (runtime), реализующая стандартную библиотеку и фундаментальные компоненты вроде Dispatch.


Главный вызов и его решение - мост к Java-миру:

Самое сложное в адаптации Swift на Android - не компиляция, а интеграция с экосистемой. Все ключевые API платформы от работы с сенсором до уведомлений заточены под Java и Kotlin. Решение этого пазла - проект Java-совместимый и два его основных инструмента: jextract и wrap-java. Они автоматически генерируют «мостики» (биндинги), используя стандартный для нативного кода механизм JNI (Java Native Interface). Это позволяет Swift-коду вызывать Java-классы и наоборот, обеспечивая бесшовную, хотя и требующую настройки, интеграцию.


Кто уже использует на практике:

Лучшее доказательство жизнеспособности технологии - ее применение в коммерческих продуктах с миллионами установок. Вот несколько примеров:

🔵Spark (Readdle): известный почтовый клиент, использующий общую Swift-логику для iOS, Android, macOS и Windows.

🔵flowkey: приложение для обучения игре на фортепиано.

🔵Naturitas: крупный маркетплейс органических продуктов.

Эти компании доказали, что общая кодовая база на Swift для бизнес-логики - не фантастика, а рабочая стратегия, экономящая ресурсы.


Что нового? Ключевые обновления SDK:

Рабочая группа активно развивает инструментарий. Среди последних значимых улучшений:

🔵Версионирование API Android. Раньше было проблематично работать с несколькими уровнями API в одном приложении. Теперь появилась поддержка знакомых по iOS-разработке атрибутов @available и проверки #available. Это позволяет писать код, который корректно работает на разных версиях ОС, повышая гибкость разработки.

🔵Ночные сборки Swift 6.3. Запущена официальная система непрерывной интеграции (CI), которая ежедневно собирает и публикует предварительные версии SDK. Это дает смелым разработчикам доступ к самым свежим изменениям и упрощает тестирование.

🔵Фокус на инструменты разработчика. В приоритете - упрощение отладки. Ведется работа по интеграции отладчика Swift и сервера LSP (sourcekit-lsp) в популярные IDE, такие как Android Studio и Visual Studio Code, чтобы процесс написания кода стал привычным и комфортным.


🔗 Ссылка на пост в блоге


💡 Вывод:

Swift на Android перестал быть диковинкой. Это формирующийся, но уже вполне рабочий технологический стек для стратегии «общая логика - нативные интерфейсы». Он предлагает мощную альтернативу C++ для критичных к производительности задач и дает iOS-разработчикам шанс выйти на новый рынок, используя знакомый язык.

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
15🔥8👍41👀1
👨‍💻 Письмо от Apple: пора обновлять Xcode и iOS SDK.

В мире iOS-разработки есть определенные сезонные ритуалы, которые повторяются из года в год. Один из них: письма от App Store Connect, которые начинают приходить разработчикам примерно через 4-6 месяцев после выхода новой версии Xcode. Эти письма не сообщают о чем-то экстраординарном, они напоминают о неизбежном: пришло время обновить инструменты и перейти на новый SDK. Если вы получили такое уведомление, не стоит паниковать - это стандартный процесс.

В последние дни многие разработчики начали получать автоматические уведомления из App Store Connect с примерно следующим содержанием: «Ваше приложение было собрано с использованием iOS 18.5 SDK. Начиная с апреля 2026 года все новые отправки в App Store должны использовать iOS 26 SDK или новее».

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


Как работает этот механизм:

🔵Сентябрь-октябрь: выход новой версии iOS и Xcode (в данном случае iOS 26 и Xcode 26)

🔵Октябрь-март: период адаптации, когда можно использовать как старый, так и новый SDK

🔵Апрель следующего года: точка перехода, когда старый SDK перестает приниматься для новых отправок

Важное уточнение: это требование касается только новых отправок и обновлений существующих приложений. Приложения, уже находящиеся в App Store, продолжают работать без изменений. Также это не означает, что ваше приложение перестанет поддерживать старые версии iOS, вы по-прежнему можете устанавливать низкий минимальный уровень Deployment Target.


Почему Apple это делает:

Причин несколько и они все рациональны:

🔵Безопасность: новые SDK содержат исправления уязвимостей.

🔵Производительность: оптимизации компилятора и рантайма.

🔵Качество экосистемы: минимизация фрагментации.

🔵Поддержка новых функций: обеспечение доступа к последнему API.


💡 Вывод:

Получение письма о необходимости обновления SDK не повод для тревоги, а стандартный рабочий процесс в экосистеме Apple. Это как ежегодный техосмотр автомобиля: необходимая процедура, которая обеспечивает безопасность и надежность.

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍9🔥4🙏2👀1🤝1
🔢 Эволюция enum: больше не надо бояться добавлять новые кейсы.

Swift всегда балансировал между безопасностью и гибкостью. С одной стороны строгий компилятор, который заставляет обрабатывать все возможные случаи. С другой - реальная разработка, где требования меняются, и API должен эволюционировать. Особенно остро это противоречие ощущалось в перечислениях: добавление нового кейса в публичный enum ломало обратную совместимость, заставляя авторов библиотек либо плодить новые типы, либо вообще избегать enum в публичном API.

С выходом Swift 6.2.3 этот многолетний компромисс наконец-то разрешается. Новый атрибут @nonexhaustive меняет правила игры, позволяя enum'ам расти без боли для пользователей библиотек.


Проблема, знакомая каждому:

Представьте библиотеку для работы с API погоды. Вы создаете enum для условий:

public enum WeatherCondition {
case sunny
case cloudy
case rainy
}


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

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


Решение -
@nonexhaustive:

Новый атрибут меняет правила игры. Помечая enum как @nonexhaustive, вы говорите компилятору: «Этот enum может расширяться в будущем».

@nonexhaustive
public enum WeatherCondition {
case sunny
case cloudy
case rainy
}


Теперь компилятор запрещает пользователям делать exhaustive switch без @unknown default. Это заставляет их заранее предусмотреть возможность будущих расширений. Когда вы позже добавите case snowy, код пользователей с @unknown default продолжит работать корректно.


Плавная миграция с
@nonexhaustive(warn):

Для существующих кодовых баз предусмотрен миграционный путь. Атрибут @nonexhaustive(warn) сначала показывает предупреждение, давая пользователям время адаптировать код, прежде чем требование станет ошибкой. Это пример вдумчивого дизайна, учитывающего реальные условия работы с legacy-кодом.


Когда что выбрать:

@frozen - для перечислений, которые фундаментальны и никогда не изменятся, как Optional или Result. Это обещание навсегда, дающее компилятору право на максимальные оптимизации.

@nonexhaustive - новый стандарт для публичных API библиотек. Подходит для статусов, кодов ошибок, категорий всего, что может эволюционировать со временем.

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


🔗 Читать подробнее


💡 Вывод:


Введение @nonexhaustive в Swift 6.2.3 - это важная веха в эволюции языка. Оно показывает зрелость Swift как платформы для создания долгоживущих, эволюционирующих систем. Язык начинает предлагать инструменты не только для написания кода, но и для управления его изменением во времени.

Это изменение признает фундаментальную истину разработки ПО: требования меняются, системы растут, и наши инструменты должны помогать нам адаптироваться к этим изменениям, а не становиться препятствием. @nonexhaustive дает библиотекам свободу развиваться, сохраняя при этом безопасность типов и ясность API - редкое сочетание, которое делает Swift еще более привлекательным для создания серьезных, долгосрочных проектов.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2214👍73🤯1🙏1
🔢 Профилирование SwiftUI в Xcode 26: находим слабые звенья в производительности.

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


Новый инструментарий - от статистики к пониманию:

Основное нововведение - специализированный SwiftUI-инструмент в пакете Instruments. В отличие от общих профилировщиков, он заточен именно под архитектуру SwiftUI, понимая такие сущности, как View, State, Binding и ObservableObject. После записи сессии профилирования инструмент предоставляет не просто сырые данные, а структурированную аналитику, сфокусированную на поведении вью.

Запустите профилирование через Product -> Profile и выберите шаблон SwiftUI. После записи действий в приложении откроется сводка «All Updates».

Отсортируйте таблицу по столбцу «Count». Первые строчки - ваши главные кандидаты на оптимизацию. Здесь вы увидите не только количество обновлений, но и суммарное время, которое на них ушло.


Настоящая магия в графе «Cause & Effect»:

Наведите на проблемный View и нажмите «Show Cause & Effect Graph». Вы увидите цепочку событий. Синие узлы - ваш код, серые - системный.

Двигайтесь по стрелкам влево от вью. Вы найдете первопричину: какое именно изменение @State, @Published или внешнее событие запустило цепную реакцию. Граф наглядно покажет, если, например, таймер обновляет данные каждую секунду, а из-за этого перерисовывается весь экран.

Этот метод эффективен для диагностики:

🔵Дрожания UI при быстром вводе символов в текстовое поле.

🔵Мерцания в бесконечных списках.

🔵Неочевидных обновлений после сетевых запросов.


🔗 Ссылка на подробную статью


💡 Вывод:

Появление специализированного SwiftUI-инструмента в Xcode 26 - это сдвиг парадигмы от эмпирической оптимизации к доказательной. Больше не нужно вслепую добавлять .equatable() или разбивать объемной иерархии вью на сабвью, надеясь на улучшение. Теперь можно:

🔵Измерить: получить точную количественную оценку проблемы.

🔵Увидеть: визуализировать всю причинно-следственную цепочку в интерактивном графе.

🔵Исправить: точно определить, какая строка кода или какое свойство является корнем проблемы.

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17941🔥1👏1
👨‍💻 Open Source как план выживания: почему Skip отказался от подписок.

Skip позиционировал себя как смелое коммерческое решение для кроссплатформенной разработки на Swift. Его бизнес-модель строилась на уникальности: плати, чтобы писать на Swift под Android. Сегодня этот эксперимент завершился капитуляцией. Объявление о переходе на полностью бесплатную open source модель - это не щедрый жест, а вынужденное признание: проект проиграл в борьбе за рынок.

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


Причина 1 - рынок отказывается платить:

В блоге Skip есть ключевая фраза: «Суровая правда в том, что разработчики ожидают получить свои инструменты бесплатно». Команда признает, что три года пыталась продавать подписки, но столкнулась с рыночной реальностью. Монетизация через IDE и сервисы платформ (App Store, Google Play) убила модель прямых продаж инструментов. Когда Apple выпустила собственный бесплатный Swift SDK для Android, уникальное торговое предложение Skip растворилось окончательно.


Причина 2 - вопрос доверия к маленькой компании:

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


Что изменилось технически:

🔵Убраны все лицензии: больше никаких ключей и trial-периодов.

🔵Открыт skipstone: ядро системы (транспиляция, плагины Xcode/SwiftPM, преобразование проектов) теперь на GitHub.

🔵Новый сайт: вся документация и ресурсы теперь доступны для всех желающих на новом сайте.


Новая экономика - от подписок к подаяниям:

Skip не стал благотворительным проектом. Команда перешла на модель выживания, зависимую от спонсорства:

🔵GitHub Sponsors для индивидуальных разработчиков.

🔵Корпоративные спонсорские пакеты для компаний.

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


Почему именно сейчас:

Выход стабильного официального Swift SDK для Android от рабочей группы, которую, сделал проприетарную часть технологии Skip менее ценной. Зачем платить за транспилятор, когда можно использовать нативную компиляцию от Apple? Открытие кода - это попытка сохранить релевантность, переместив фокус с «уникальной технологии» на «сообщество и экосистему».


🔗 Ссылка на пост в блоге


💡 Вывод:

Переход Skip в open source - это не победа сообщества, а капитуляция перед рыночными условиями. Для индустрии это сигнал: рынок инструментов для разработки становится еще более беспощадным. Если ваше решение конкурирует с бесплатными инструментами гигантов (Apple, Google, Microsoft), ваша бизнес-модель обречена. Единственный шанс - либо мгновенный взрывной рост с последующей покупкой гигантом, либо немедленный переход в open source с надеждой на спонсорство.

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥1142🤔1👀1🫡1
Forwarded from Кот Денисова
👨‍💻 Почему не стоит бояться, что ИИ заберет вашу работу.

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


Почему ИИ не заменит разработчиков:

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

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


ИИ как инструмент повышения эффективности:

Современные разработчики используют ИИ для:

🔹Автоматизации рутины (написание тестов, документация).
🔹Решения стандартных задач.
🔹Поиска идей и решений в сложных ситуациях.

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


Новые возможности вместо угроз:

Развитие ИИ создает спрос на новые специализации:

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

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


Что действительно изменилось:

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

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


💡 Вывод:

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

ИТ не умирает, а трансформируется. И те, кто успеет адаптироваться к новым условиям, окажутся в выигрыше.


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🙏94🔥1👀1
👨‍💻 Почему новые фичи убивают приложение на слабых устройствах и как это исправить.

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


Когда улучшения становятся проблемой:

Представьте типичный сценарий: команда внедряет красивую, ресурсоемкую фичу: детализированную 3D-графику, сложную анимацию, работу с большими данными в реальном времени. A/B-тесты показывают, что пользователям нравится. Но параллельно растет метрика аварийных завершений. Причем не равномерно, а взрывно на определенном сегменте устройств.

Анализ показывает, что проблема в Out of Memory (OOM). Приложение перестает помещаться в оперативную память, и система его завершает. Оказывается, для 10% пользовательских сессий (чаще всего на устройствах с 2-3 ГБ ОЗУ) новые фичи становятся неподъемными. Эти 10% сессий генерируют до 90% всех OOM-крашей.


От диагностики к архитектурному решению:


Шаг 1. Поиск точки невозврата:

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

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

Шаг 2. Отказ от универсальности:

Традиционный подход «одно приложение для всех» перестает работать, когда разброс характеристик устройств слишком велик. Устройство с 2 ГБ ОЗУ и устройство с 8 ГБ - это по сути разные вычислительные среды. Невозможно писать код, одинаково эффективный в обоих случаях.

Решение: явное разделение аудитории по классам памяти (RAM-классам). Устройства группируются не по марке или году выпуска, а по реально доступному объему оперативной памяти. Это создает основу для адаптивного поведения.

Шаг 3. Система адаптивной функциональности:

Ядро решения - конфигурируемый набор функций для каждого RAM-класса. На низких классах отключаются или упрощаются наиболее ресурсоемкие фичи (детализированная графика, предзагрузка объемных данных, фоновые процессы). На высоких - все возможности доступны по умолчанию. Ключевые принципы такой системы:

🔵Автоопределение: приложение само при старте определяет свой RAM-класс на основе системных API. Никаких опросов пользователей или загрузок конфигов вслепую.

🔵Централизованное управление: набор доступных функций для каждого класса управляется через удаленные конфиги. Это позволяет быстро реагировать на проблемы и гибко тестировать границы.

🔵Честные A/B-тесты: эксперименты с тяжелыми фичами изначально настраиваются так, чтобы не доходить до устройств, которые заведомо не потянут новую функциональность. Это защищает метрики стабильности и не портит опыт слабым устройствам.


Шаг 4. Новые метрики для нового подхода:

С внедрением RAM-классов картина стабильности перестала быть общей. Теперь команда отслеживает ключевые метрики (OOM-краши, потребление памяти, Crash-Free сессии) в разрезе каждого класса. Это позволяет принимать взвешенные решения: «Эта фича добавляет 10% к памяти на классе 3. Готовы ли мы поднять для него минимальные требования?».


🔗 Ссылка на подробную статью


💡 Вывод:

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

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥94🤯1👀1
🔢 🪟 Swift на Windows: очередной выход Swift за пределы экосистемы Apple.

Swift больше не довольствуется ролью языка для техники Apple. Создание официальной рабочей группы Windows - это переход от экспериментов к планомерному захвату чужой территории. Теперь у языка есть боевой штаб для системной атаки на крепость Microsoft.


Что было раньше:

До 2026 года Swift на Windows существовал в режиме «кто во что горазд». Компилятор работал, но ключевые библиотеки (Foundation, Dispatch) были нестабильны. Сборка и дистрибуция приложений превращались в квест.


Что изменилось сейчас:

Создана официальная структура с конкретными целями:

🔵Стабильные сборки: обеспечить рабочий дистрибутив Swift для Windows.

🔵Адаптация ядра: заставить Foundation и Dispatch работать по-человечески на Windows.

🔵Стратегия: определить, как Swift будет развиваться на этой платформе.

🔵Интеграция: найти способы связать Swift с Win32 API и COM.


Почему это важно:

🔵Для iOS-разработчиков: появится возможность писать нативные инструменты и утилиты для Windows, не переучиваясь на C#.

🔵Для компаний: Swift сможет претендовать на проекты в корпоративной среде, где доминирует Windows.

🔵Для языка: это шаг к статусу по-настоящему кроссплатформенного языка, а не нишевого решения для Apple.


Главный вызов:

Проблема не в компиляции, а в экосистеме. Swift должен научиться жить в мире WinAPI, COM-объектов и .NET. Нужны мосты, аналогичные JNI для Android, но для Windows.


🔗 Ссылка на пост в блоге


💡 Вывод:

Создание рабочей группы - это не про улучшение сборок. Это декларация войны с C# и C++ на их собственном поле. Swift перестает быть гостем на Windows и начинает борьбу за место под солнцем. Успех этой операции покажет, сможет ли язык от Apple стать реальной силой в мире разработки под Windows или останется экзотическим выбором для Windows-энтузиастов.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1793👍1👏1
💻 VS Code для iOS-разработки: добавляем просмотр .xcassets как в Xcode.

Тренд на миграцию iOS-разработчиков с Xcode на VS Code или Cursor набирает обороты. Однако переход часто упирается в потерю специфичных инструментов Apple-экосистемы. Один из самых болезненных моментов - работа с Asset Catalogs (.xcassets). В Xcode это интуитивный визуальный редактор, в VS Code - папка с JSON-файлами. Разработчики из сообщества решили проблему, создав расширение, которое буквально переносит знакомый интерфейс Xcode в новый редактор.


Суть проблемы - JSON вместо интерфейса:

Файл .xcassets - это не просто папка с картинками. Это структурированный каталог, содержащий:

🔵Наборы изображений (Image Sets) для разных разрешений и устройств.

🔵Цветовые палитры (Color Sets) с поддержкой тем и контрастности.

🔵Иконки приложений (App Icon Sets).

🔵Данные (Data Sets).

🔵Анимации Lottie.

В Xcode разработчик видит удобное древовидное представление с превью. В голом VS Code - только сырые Contents.json файлы и изображения, что делает навигацию и проверку мучительно медленной.


Решение- Asset Catalog Viewer:

Расширение полностью копирует трехпанельную логику интерфейса Xcode:

🔵Левая панель: иерархическое дерево ассетов с папками и миниатюрами.

🔵Центральная панель: детальное превью выбранного ассета со всеми его вариантами (разрешения, темы, устройства).

🔵Правая панель: инспектор свойств - показывает метаданные, цветовые пространства, размеры файлов.


Установка:

Расширение устанавливается стандартно через каталог расширений VS Code или Cursor. После установки оно добавляет в контекстное меню (по правому клику на папке .xcassets) пункт «Open Asset Catalog Viewer». Также можно открыть каталог через Command Palette. Расширение работает локально, не требуя отправки данных.


🔗 Ссылка на расширение


💡 Вывод:

Пока Apple сохраняет Xcode как единственную официальную, но тяжелую и не всегда стабильную IDE, сообщество берет инициативу в свои руки, выборочно перенося лучшие ее части в более современные и гибкие редакторы: VS Code и Cursor.

Этот тренд важен: он дает разработчикам реальный выбор. Больше не нужно мириться со всеми недостатками Xcode ради работы с ассетами или, наоборот, отказываться от удобства ради скорости и стабильности VS Code. Теперь можно собрать идеальный стек инструментов под свои задачи. Asset Catalog Viewer - это убедительный аргумент в пользу того, что будущее iOS-разработки может быть не за монолитной IDE, а за модульной средой, где каждую функцию можно выбрать и улучшить независимо.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍8🤯2👀21🤔1
🔢 UIKit встречает Liquid Glass: как адаптировать гибридное приложение к iOS 26.

С выходом iOS 26 и нового дизайна Liquid Glass многие команды столкнулись с неочевидными вызовами. Особенно сложная ситуация складывается у проектов с гибридной архитектурой, где UIKit и SwiftUI соседствуют годами. Адаптация - это не просто замена цветов и добавление размытий. Это переосмысление навигации, модальностей и даже базовых компонентов интерфейса. На примере приложения Grow, получившего признание редакции App Store в 173 странах, разберем, какие решения работают на практике, а какие оказываются тупиковыми.


Двойная стратегия - совместимость и прогрессивность:


Первое и главное правило успешной адаптации - сохранение работоспособности для пользователей старых версий iOS. В Grow выбрали стратегию условной компиляции и проверки доступности API через #available(iOS 26.0, *). Это позволяет:

🔵Оставлять проверенные интерфейсы для iOS 18 и ниже.

🔵Предлагать новый визуальный опыт пользователям iOS 26.

🔵Постепенно мигрировать компоненты не поломав существующую логику.


Навигация - от кастомных решений к нативным компонентам:

Исторически сложилось, что многие проекты заменяли UINavigationBar кастомными view для сложных UI-элементов. Liquid Glass требует обратного подхода - возврата к нативным компонентам. В Grow провели рефакторинг:

🔵Заменили кастомные панели навигации на UINavigationController.

🔵Настроили navigationItem для размещения элементов управления.

🔵Использовали Auto Layout для правильного позиционирования scroll-контейнеров.

Ключевой момент: нативные компоненты лучше адаптируются к системным эффектам морфинга и анимациям Liquid Glass.


Модальные представления:

Адаптация UISheetPresentationController оказалась одной из самых простых задач. Для активации эффектов Liquid Glass достаточно:

🔵Убрать кастомные фоновые view.

🔵Использовать системные API для управления размытием краев.

🔵Настраивать ToolbarItem для контроля Scroll Edge Effect.

Более интересной задачей стала реализация морфинг-меню в формате popover. Вместо чисто SwiftUI-решений команда выбрала гибридный подход через UIPopoverPresentationController:

🔵SwiftUI-view упаковывается в UIHostingController.

🔵Контроллер привязывается к UIBarButtonItem через popoverPresentationController?.sourceItem.

🔵Делегат UIPopoverPresentationControllerDelegate решает проблемы приоритета жестов и предварительной настройки контента.


Расширение возможностей - стеклянный текст:

Один из наиболее креативных аспектов адаптации - создание кастомных стеклянных эффектов. Используя Core Text, можно преобразовывать глифы шрифтов в CGPath, а затем применять к ним эффект glassEffect(_:in:). Это открывает возможности для:

🔵Текстовых элементов с эффектом жидкого стекла.

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

🔵Динамических эффектов, зависящих от контента.


🔗 Ссылка на подробную статью


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍179🔥31🙏1
🔨 Xcode 26.3: добавлена поддержка Claude, Codex и MCP агентов.

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


Новая парадигма - от инструкций к целям:


Раньше работа с ИИ напоминала разговор с очень умным, но слепым помощником: «напиши функцию для парсинга JSON», «создай вью с такими-то свойствами». В Xcode 26.3 подход меняется. Вы формулируете цель: «Добавь в приложение прогноз погоды на семь дней с использованием WeatherKit и стилем Liquid Glass».

Система, используя интеграцию с Claude Agent SDK и другими движками через Model Context Protocol (MCP), берет на себя всю остальную работу:

🔵Анализ проекта: агент изучает структуру файлов, существующие модули и зависимости.

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

🔵Исполнение: пишет код, добавляет ресурсы, настраивает проект.

🔵Верификация и итерация: запускает сборку, анализирует ошибки компиляции, использует Xcode Previews для визуальной проверки интерфейса и вносит правки, пока результат не будет соответствовать задаче.


Ключевое отличие - закрытие цикла обратной связи:

Самая мощная часть новой системы - способность агента видеть результат своей работы. Через интеграцию с Xcode Previews агент может сделать скриншот собираемого интерфейса, проанализировать его и понять: «Текст не помещается», «Отступы не соответствуют макету», «Цвета выглядят не так». Это позволяет ему самостоятельно итерироваться, не требуя постоянного вмешательства разработчика.


Что это меняет для разработчика:

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

🔵Прототипирование ускоряется в разы. Создание рабочего макета сложной фичи по описанию теперь занимает минуты. Можно быстро проверить гипотезу и показать идею.

🔵Агенты помогают с легаси-кодом. Они могут анализировать устаревшие модули, предлагать план рефакторинга и даже генерировать часть миграционного кода.

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


🔗 Ссылка на подробную статью


💡 Вывод:


Выход Xcode 26.3 - это не просто обновление с новыми ИИ-фичами. Это фундаментальное изменение архитектуры самой IDE. Apple превращает Xcode из инструмента для написания кода в платформу для оркестрации автономных агентов, которые понимают структуру проекта, умеют его собирать и даже визуально проверять результат через Previews.

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

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥209👍4👀2🙏1
🔨 Universal Links: что скрыто за простым AASA-файлом.

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

Когда пользователь кликает на Universal Link, iOS проверяет не ваш сервер напрямую. Система обращается к CDN Apple (app-site-association.cdn-apple.com), где кешируются AASA-файлы со всего мира. Ваш файл на сервере - лишь источник для этого кеша. Обновление в CDN происходит с задержкой до нескольких часов, и пока изменения не распространятся, часть пользователей будет видеть старую конфигурацию.


Критическая проблема - неявные ошибки конфигурации:

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

🔵Неправильные wildcard-паттерны (*, ?, ?*).

🔵Ошибки в substitution variables для локализаций.

🔵Конфликтующие правила исключений (exclude).

🔵Некорректные пути для query-параметров или фрагментов.

iOS не сообщает об этих ошибках. Ссылки просто перестают открываться в приложении, падая в Safari.


Стратегия надежного деплоя - четыре уровня защиты:

🔵Валидация схемы (JSON Schema) в CI. Прежде чем файл попадет на сервер, автоматика проверяет его структуру. Это отлавливает опечатки в названиях полей, неправильные типы данных, отсутствие обязательных секций. Схема описывает не только applinks, но и опциональные разделы вроде webcredentials.

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

🔵Регрессионное тестирование ссылок. Для каждого домена ведется файл-конфигурации, который нужно тщательно тестировать.

🔵Стендинг-окружение с реальными доменами. Тестировать на локальном localhost или симуляторе недостаточно. Нужны настоящие домены с HTTPS, зеркалирующие прод. В debug-сборках приложения указываются эти тестовые домены, что позволяет проверять изменения без риска для пользователей.


Wildcard-паттерны - собственная математика Apple:

Синтаксис *, ? и ?* в AASA - это не стандартные regex. Нужно понимать их преобразование:

* -> .* (ноль или больше символов)

? -> . (ровно один символ)

?* -> .+ (один или больше символов)

Самый сложный случай - substitution variables для локализаций:

"substitutionVariables": {
"menu": ["speisekarte", "menu", "carte"]
}


Паттерн /$(lang)/$(menu)/* должен корректно матчиться на /de/speisekarte/restaurant и /en/menu/restaurant. Реализация собственного парсера, который раскрывает переменные и преобразует паттерны - необходимость для нетривиальных проектов.


Особые случаи поведения iOS:

🔵Первая установка: если пользователь установил приложение по Universal Link, данные о ссылке могут не передаться в первый запуск.

🔵Холодный vs теплый запуск: поведение может отличаться в зависимости от того, было ли приложение в памяти.

🔵Developer Mode: для отладки можно добавить ?mode=developer к домену в entitlements, чтобы iOS брала файл напрямую с сервера, минуя CDN.


🔗 Ссылка на подробную статью


💡 Вывод:

Работа с Universal Links в крупном проекте - это не про добавление файла на сервер, а про построение полного жизненного цикла конфигурации. От валидации схемы и тестирования паттернов до мониторинга расхождений с CDN Apple.

Проблемы Universal Links редко проявляются сразу. Они накапливаются. Единственный способ избежать этого - относиться к AASA не как к статическому файлу, а как к критическому компоненту инфраструктуры со своим пайплайном деплоя, тестирования и мониторинга.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥7🙏21👀1🤝1
Forwarded from Кот Денисова
👨‍💻 Не ждите повышения: почему смена работы - эффективная карьерная стратегия.

Привет, друзья! Сегодня поговорим на волнующую тему: карьерном застое. Многие из нас талантливые и опытные разработчики, которые годами могут оставаться на одной позиции, питая надежду, что компания вот-вот оценит нашу преданность и труд. Нас держит чувство стабильности, вера в справедливость и нежелание покидать зону комфорта, но в современном ИТ-мире эта стратегия все чаще оказывается проигрышной. Сейчас разберемся почему.


Жесткие рамки системы:

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

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


Сигналы, которые кричат о необходимости перемен:

Прошлый пример не редкое исключение, а скорее закономерность. Вот основные сигналы, указывающие, что пора активнее рассматривать рынок труда:

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

🔹Вы достигли потолка. Вы давно освоили все задачи на своей позиции, но новых вызовов и перспектив не видите. Проекты стали рутиной.

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


Как подготовиться к смене работы:

🔹Проработайте резюме. Сместите акцент с перечисления обязанностей на ваши конкретные достижения и результаты. Используйте цифры и факты.

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

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

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


💡 Вывод:

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

Смена работы - это не про предательство, а про заботу о своем профессиональном развитии и благополучии.


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍19🔥74🤔1🙏1👀1
🔢 Новый стандарт Apple: async/await вместо Combine.

В файле репозитория, который содержит системные подсказки и документацию из Xcode 26.3 явно указано: «Избегайте использования фреймворка Combine, вместо этого предпочтительнее использовать async/await версии API». Это заметил Артем Новичков и сообщил в своем посте.

Это не приговор, а четкий сигнал от Apple о приоритетах для нового кода. Combine - зрелый и мощный фреймворк, но для большинства современных задач (сетевые запросы, работа с файлами, обновленные системные API) async/await предлагает более простую, читаемую и интегрированную в язык модель.


Что это означает:

🔵Новые проекты: логично стартовать с async/await как основного инструмента для асинхронности.

🔵Существующие проекты на Combine: не нужно срочно все переписывать. Combine остается отличным выбором для сложной реактивной логики UI или работы с легаси.

🔵Общая тенденция: Apple планомерно обновляет свои API, добавляя async/await альтернативы. Со временем это станет стандартом де-факто для новых разработок.


💡 Вывод:

Combine остается рабочим инструментом, но для всех новых разработок без сомнений выбирайте async/await - это официальный вектор развития от Apple.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
17🤯11👍7🔥4👀2🫡21
🔢 Обратная миграция: почему крупные проекты смотрят в сторону UIKit.

Последние несколько лет SwiftUI позиционировался как будущее разработки под Apple-экосистему. Однако в 2024-2025 годах наметился парадоксальный тренд: все больше разработчиков и компаний сознательно возвращаются к классическому стеку - UIKit. Это не просто ностальгия по старым методам, а стратегическое переосмысление выбора инструментов в новых условиях.


Смена приоритетов - от скорости написания к скорости чтения и контролю:

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

Однако с повсеместным внедрением ИИ-инструментов (Copilot, Cursor, Claude Code) парадигма сместилась. Писать код становится проще, а читать и поддерживать - сложнее. И здесь UIKit с его императивным, явным стилем выигрывает.

🔵Прямолинейность UIKit: архитектура MVC/MVVM задает четкую структуру. Вы точно знаете, где искать логику жестов (UIGestureRecognizer во viewDidLoad), где обновляется layout (viewDidLayoutSubviews), и как данные попадают в представление. Это предсказуемо и легко читается как человеком, так и ИИ-ассистентом.

🔵Магия SwiftUI: мощные property wrappers (@State, @Binding, @EnvironmentObject) и модификаторы создают сложные, неочевидные связи данных. Чтобы понять поток информации в нетривиальном экране, часто приходится «разматывать» цепочки зависимостей, что замедляет ревью и рефакторинг.


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

SwiftUI поощряет минималистичные архитектуры вроде Model-View (MV), где бизнес-логика, состояние и представление часто перемешаны в одном файле. Это отлично для простых экранов, но превращается в кошмар для сложных, долгоживущих проектов.

UIKit, со своей «многословной» архитектурой, вынуждает к дисциплине. Разделение ответственности между ViewController, Model и Router/Coordinator создает каркас, который:

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

🔵Облегчает работу ИИ. Четкий запрос вроде «добавь обработку свайпа в делегат коллекции в CollectionViewController» дает более точный и интегрируемый результат.

🔵Дает полный контроль. Прямой доступ к жизненному циклу view (viewWillAppear, viewDidDisappear), нативным делегатам (UIScrollViewDelegate, UICollectionViewDelegate) и методам анимации (UIView.animate) остается незаменимым для создания сложных взаимодействий.


🔗 Ссылка на подробную статью


💡 Вывод:

Выбор между UIKit и SwiftUI больше не является линейным путем «от старого к новому». Это стратегическое решение, основанное на контексте проекта:

🔵Выбирайте SwiftUI, если: вы создаете MVP, простые кроссплатформенные приложения (с SwiftUI на macOS/watchOS) или внутренние инструменты, где скорость создания важнее тонкой настройки и долгосрочной поддержки.

🔵Выбирайте UIKit, если: вы строите большое, сложное приложение с требованием к нативной производительности, кастомными, сложными взаимодействиями, долгим циклом жизни и командой, где читаемость и поддерживаемость кода - приоритет.

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19124🔥1🤔1👀1
🔢 От хаоса к порядку: Swift делает поведение nonisolated функций предсказуемым.

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


Суть проблемы - разрыв между ожиданием и реальностью:

Когда вы вызываете nonisolated асинхронный метод из актора, компилятор вынужден применять строгие Sendable-проверки ко всем аргументам, даже если метод по своей природе не должен покидать контекст актора. Это приводит к ложным ошибкам, особенно в библиотечном коде, где автор API может не предусмотреть такой сценарий. Даже стандартная библиотека Swift Concurrency сталкивалась с этой проблемой.


Решение - явное управление изоляцией через новые модификаторы:

Предложение SE-0461 вводит два новых инструмента для точного контроля:

🔵nonisolated(nonsending) - явно указывает, что асинхронная функция должна выполняться в контексте вызывающего актора (унаследовать его изоляцию). Это поведение становится предсказуемым и аналогичным синхронным функциям.

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

class NotSendable {
nonisolated(nonsending)
func performAsync() async {
// Работает в контексте вызывающего актора
}
}

actor MyActor {
let item = NotSendable()

func call() async {
item.performSync() // OK
await item.performAsync() // Теперь тоже OK, ошибки типов нет!
}
}



Макрос #isolation и работа с замыканиями:

Для продвинутых сценариев, таких как создание оберток (например withResource), расширяется функциональность макроса #isolation. Теперь он может корректно передавать контекст изоляции в nonisolated(nonsending) функции, что делает написание высокоуровневых асинхронных API значительно проще и безопаснее.

Важное уточнение: неструктурированные задачи (Task { }), созданные внутри таких функций, по-прежнему не наследуют изоляцию, что соответствует принципам предсказуемости.


Практический смысл - баланс между безопасностью и удобством:

Это изменение - не просто синтаксический сахар. Оно решает фундаментальную проблему: делает поведение nonisolated функций последовательным и интуитивно понятным. Разработчики получают явный контроль:

🔵Хотите, чтобы функция работала в том же контексте и не требовала Sendable? Используйте nonisolated(nonsending).

🔵Нужно гарантированно переключиться для параллельной работы? Явно укажите @concurrent.


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥168👀41👍1🤔1
🔢 Swift: профессиональные методы отладки сложного кода.

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


Трюк с контекстом - почему ваши логи должны быть умнее print:

Стандартный print оставляет вас в неведении: где именно сработал этот вывод? Вместо этого используйте встроенные литералы компилятора для автоматического контекста:


func debugLog(
_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line
) {
let fileName = URL(fileURLWithPath: file).lastPathComponent
print("[\(fileName):\(line)] \(function) — \(message)")
}


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


Зеркало в runtime - когда нужно увидеть то, что скрыто:

Swift - статически типизированный язык, но это не значит, что мы не можем исследовать объекты в рантайме. Mirror - ваш портал для интроспекции. Допустим, у вас сложная ViewModel с десятком @Published свойств, и вы не понимаете, какое именно вызывает неожиданное обновление UI:


func inspectObject(_ object: Any) {
let mirror = Mirror(reflecting: object)
for child in mirror.children {
print("\(child.label ?? "Unknown"): \(type(of: child.value)) = \(child.value)")
}
}


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


dump() против print - анатомия сложных структур:

Когда print выдает что-то вроде User(address: __lldb_expr_123.Address(street: "...", ...)), пора переходить к dump(). Эта функция рекурсивно обходит всю структуру объекта, показывая его реальное дерево:


struct Project {
let title: String
let contributors: [Developer]
let settings: Configuration
}

let activeProject = fetchCurrentProject()
dump(activeProject) // Полное дерево со всеми вложенными объектами


Вы увидите не просто «есть массив разработчиков», а каждого разработчика со всеми его полями, и каждое поле конфигурации. Это спасение при работе с Core Data (исследование графа объектов), сложными JSON-ответами API или глубокими иерархиями UIView.


CustomDebugStringConvertible - создание отладочной документации:

Реализация CustomDebugStringConvertible - это не про красивый вывод. Это про создание специализированного отладочного представления для ваших типов, которое показывает именно ту информацию, которая важна для диагностики:


class NetworkRequest: CustomDebugStringConvertible {
let id: UUID
let endpoint: URL
var state: State
var metrics: [Metric]

var debugDescription: String {
"""
Request \(id.uuidString.prefix(8))...
to \(endpoint.path)
is \(state.rawValue)
last metric: \(metrics.last?.description ?? "none")
"""
}
}


Теперь, логгируя или используя po в LLDB, вы мгновенно видите статус запроса, а не просто его адрес в памяти. Это особенно эффективно для массивов или словарей таких объектов.


🔗 Ссылка на подробную статью


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1910👍31🙏11
🔢 Тихий режим для push-уведомлений: обход системных ограничений iOS.

Отключить звук уведомлений - кажется, одна из самых простых пользовательских настроек. Но для iOS-разработчика эта кнопка превращается в сложную архитектурную задачу. Почему? Потому что звук push-уведомления контролируется не приложением, а серверным payload, который iOS исполняет как приказ. Пользователь ждет тишины, а система послушно проигрывает звук из этого самого payload. Разрыв между ожиданием и реальностью можно устранить, но для этого потребуется нестандартный подход, затрагивающий саму цепочку доставки уведомления.


Архитектурная головоломка и ее решение:

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

Ключ к решению - App Groups. Это технология, позволяющая выделить область общей памяти, доступную для нескольких компонентов одного приложения (основной таргет и экстеншены). Настройка происходит через добавление кастомной capability в оба таргета и использование идентичного suiteName для инициализации UserDefaults(suiteName:).


Сердце системы - Notification Service Extension:

Этот extension - единственная точка в системе iOS, где можно программно модифицировать контент удаленного уведомления до его показа пользователю. Он активируется системой при получении пуша, имеет строго ограниченное время на выполнение (порядка 30 секунд) и должен вызвать contentHandler. Логика работы экстеншена:

🔵Получить входящий контент (UNNotificationRequest).

🔵Проверить в общих UserDefaults (через App Group), активен ли звук в настройках приложения.

🔵Если звук отключен - удалить свойство .sound из UNMutableNotificationContent.

🔵Передать модифицированный контент в contentHandler.

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


Синхронизация состояния - менеджер настроек:

В основном приложении необходим менеджер, который будет записывать значение настройки звука одновременно в стандартные UserDefaults (для быстрого доступа в самом приложении) и в общие UserDefaults App Group (для доступа extension). Это гарантирует консистентность данных независимо от того, запущено ли основное приложение в момент прихода пуша.


Обработка в foreground - делегат центра уведомлений:

Extension работает только для уведомлений, пришедших, когда приложение в фоне или заблокировано. Для случая, когда приложение активно, модификацию необходимо проводить в методе userNotificationCenter(_:willPresent:withCompletionHandler:). Здесь, основываясь на тех же настройках, мы определяем, передавать ли в completionHandler опцию .sound.


Критически важные детали реализации:

🔵Членство в таргетах (Target Membership): файлы, которые должны быть доступны и основному приложению, и extension (например кастомный звуковой файл или GoogleService-Info.plist для Firebase), должны быть отмечены галочками в обоих таргетах.

🔵Точность идентификатора App Group: строка-идентификатор в .entitlements файлах должна быть абсолютно идентичной в основном таргете и в таргете extension. Чувствительна к регистру.

🔵Ограничение времени: код в didReceive extension должен быть максимально эффективным. Если обработка не успевает, система вызовет serviceExtensionTimeWillExpire, где нужно отдать хотя бы исходный контент.


🔗 Ссылка на подробную статью


💡 Вывод:

Реализация пользовательского управления звуком уведомлений - это блестящий пример того, как понимание архитектурных возможностей iOS позволяет создавать кастомный UX вопреки ограничениям стандартных API. Решение элегантно обходит главное препятствие: отсутствие возможности напрямую влиять на серверный payload.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍9🔥3🤔1🙏11
🔢 Как работает UUID() в Swift и почему он никогда не повторяется.

Когда вы пишете let id = UUID(), кажется, что это просто генерация случайного набора символов. На деле Swift запускает целый конвейер: собирает случайные данные из множества аппаратных датчиков: от колебаний напряжения в процессоре до микрозадержек при доступе к памяти, превращает их в непредсказуемые числа через сложные криптоалгоритмы и упаковывает результат в формат по международному стандарту. И все это происходит быстрее, чем вы успеваете моргнуть.


Три стратегии, одна цель:


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

🔵Версия 1 (таймстемп + MAC). Самый старый подход. Берет текущее время с точностью до 100 наносекунд, добавляет MAC-адрес сетевой карты и номер такта на случай отката времени. Гарантия уникальности абсолютная, но есть нюанс: MAC-адрес светит железо, на котором сгенерирован UUID. Для распределенных систем это допустимо, для пользовательских приложений - потенциальная угроза приватности.

🔵Версия 4 (полностью случайная). Это то, что делает стандартный UUID() в Swift. Никакого времени, никакого железа - только 122 бита криптостойкой случайности. Шесть бит зарезервировано под версию и вариант, остальное - энтропия. Вероятность коллизии настолько мала, что ее можно игнорировать даже при генерации миллиардов идентификаторов в секунду.

🔵Версия 7 (время + случайность). Новейший стандарт, который пока не встроен в Swift напрямую, но уже активно обсуждается. Берет миллисекундный timestamp и добивает случайными битами. Главное преимущество - монотонность: такие UUID можно сортировать по времени создания, что критично для баз данных и событийных логов.


Откуда берется «достаточно случайно»:

Случайность бывает разная. arc4random() - быстрая, но предсказуемая, если знать состояние генератора. UUID требует другого уровня - CSPRNG (Cryptographically Secure PseudoRandom Number Generator). В Apple-экосистеме за это отвечает Security.framework, который собирает энтропию буквально из всего:

🔵Квантовый шум транзисторов CPU (тепловые флуктуации электронов).

🔵Джиттер тактовых частот между ядрами.

🔵Вариации времени доступа к RAM и кешу.

🔵Тайминги нажатий на экран (для iOS) или движений мыши (для macOS).

🔵Шум сенсоров (акселерометр, гироскоп, тепловые датчики).

🔵Сетевые пакеты и их интервалы.

Все это смешивается в системном пуле энтропии, через который прогоняется криптопримитив (например, ChaCha20 или Fortuna), и только потом отдается в UUID().


Почему это не тормозит:

Несмотря на сложность, генерация UUID в Swift - одна из самых быстрых операций. На современном железе: 2-5 миллионов идентификаторов в секунду. Секрет в том, что пул энтропии поддерживается постоянно, а CSPRNG просто выдает из него уже готовые случайные байты. Тяжелая работа (сбор физического шума) происходит в фоне, а ваш UUID() забирает готовый результат.


🔗 Ссылка на подробную статью


💡 Вывод:

UUID в Swift - это не просто рандомайзер. Это прослойка между вашим кодом и физическими процессами внутри чипа, которые фундаментально непредсказуемы. Каждый вызов UUID() - маленькое чудо инженерной мысли, где квантовая механика встречается с RFC-стандартами, а результат умещается в 36 символов. Шанс, что два UUID совпадут, настолько мал, что вы скорее встретите медведя в метро, чем поймаете коллизию.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍169🔥3🤔1🙏1👀1
Forwarded from Кот Денисова
👨‍💻 Карьера junior-разработчика: что изменилось с приходом ИИ.

Всем привет! Ситуация на рынке junior-вакансий сегодня действительно непростая. Если раньше компании охотно брали начинающих разработчиков на вырост, то сейчас подход кардинально изменился. Давайте разберемся, что происходит и как адаптироваться к новым реалиям.


Почему компании стали реже нанимать джунов:

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

Типичные джуновские задачи, которые теперь автоматизируются:

🔹Верстка стандартных компонентов.
🔹Написание шаблонного кода.
🔹Разработка простого API.
🔹Багфиксы очевидных ошибок.


ИИ как катализатор изменений:


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

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


Новые требования к начинающим специалистам:

Сейчас требования на позицию junior-разработчика еще недавно являлись требованиями на позицию middle-разработчика и включают:

🔹Умение работать в команде без постоянного контроля.
🔹Способность самостоятельно разбираться в сложных задачах.
🔹Понимание архитектурных принципов.
🔹Навыки работы с ИИ-инструментами.


Что делать начинающим разработчикам:

Прокачивать автономность:

🔹Учитесь самостоятельно находить решения.
🔹Развивайте навыки декомпозиции задач.
🔹Практикуйтесь в code review.

Осваивать ИИ-инструменты:

🔹Изучайте эффективные промпты.
🔹Освойте работу с Copilot, Cursor, ChatGPT.
🔹Учитесь проверять и рефакторить код, сгенерированный ИИ.

Фокусироваться на качестве кода:

🔹Вместо количества решенных задач — акцент на качестве решений
🔹Изучайте лучшие практики и паттерны проектирования.
🔹Развивайте архитектурное мышление.


💡 Вывод:

Современный junior-разработчик - это не просто человек, который пишет код. Это специалист, который умеет эффективно работать в связке с ИИ-инструментами, быстро обучается и способен брать ответственность за свои решения. Те, кто адаптируется к новым условиям, получат серьезное конкурентное преимущество.


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥6👀2🗿21
👣 Flutter 3.41: стабильность, модульность и подготовка к будущему

Google выпустил Flutter 3.41 - релиз, который выглядит как плановый апдейт, но на самом деле закладывает архитектурные изменения на годы вперед. 868 коммитов от 145 контрибьюторов, но главное не в количестве, а в направлении.


Прозрачность разработки:

Впервые Flutter вводит публичные release-окна на весь 2026 год. Теперь каждый знает точные даты заморозки веток: 3.44 выйдет в мае, 3.47 в августе, 3.50 в ноябре. Для команд, которые зависят от стабильности фреймворка, это снимает огромный пласт неопределенности. Больше не нужно гадать, попадет ли фича в ближайший релиз - календарь открыт.


Материалы и Cupertino уходят в отдельные пакеты:

Это ключевое изменение, которое многие недооценят. Material и Cupertino больше не будут привязаны к монолитному циклу релиза Flutter. Их обновления смогут выходить независимо, в любое время. Для разработчиков это означает две вещи: во-первых, вы сможете получать новые дизайн-системы (вроде Material 3 Expressive или Liquid Glass) не дожидаясь квартального обновления движка. Во-вторых, если вы застряли на старой версии Flutter из-за легаси, вы все равно сможете обновить визуальную часть отдельно. Фреймворк становится конструктором, а не монолитом.


iOS: UIScene по умолчанию и чистый blur:

Flutter окончательно прощается с наследием AppDelegate. Поддержка UIScene включена по умолчанию - это было требование Apple для будущих версий iOS, и теперь оно выполнено. Параллельно Impeller получил улучшенный рендеринг размытия: исчезли цветные ореолы по краям, которые раньше портили впечатление от BackdropFilter. CupertinoSheet обзавелся нативным drag-хендлом - мелочь, но именно из таких мелочей складывается ощущение «родного» интерфейса.


Android: подготовка к AGP 9 с осторожностью:

Важный нюанс: обновляться на Android Gradle Plugin 9 пока нельзя. Поддержка заморожена до аудита обратной совместимости. Но новые плагины уже по умолчанию генерируются на Kotlin DSL - индустрия движется, и Flutter движется с ней. Плюс появилась возможность точечно исключать ассеты для конкретных платформ: тяжелые десктопные текстуры больше не придется тащить в мобильную сборку.


Графика: синхронные текстуры и 128-битные float:

Для тех, кто работает с кастомными шейдерами, релиз принес две важные вещи. Первая - синхронное декодирование текстур. Раньше создание текстуры для шейдера могло «уронить» кадр, теперь это делается в том же фрейме через decodeImageFromPixelsSync. Вторая - поддержка 128-битных float-текстур. Это про LUT для цветокоррекции, про SDF-шейдеры и про фотофильтры на GPU. Технический потолок поднят.


🔗 Ссылка на подробное описание релиза


💡 Вывод:

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

Выделение Material и Cupertino в независимые пакеты ломает многолетнюю монолитность - теперь дизайн-системы могут эволюционировать со скоростью индустрии, а не со скоростью движка.

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


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍6🙏21👀1