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

Когда создаешь структуру в Swift, интуитивно кажется, что ее размер должен равняться сумме размеров параметров. Int - 8 байт, String - 16, Bool - 1. Сложил и получил 25. Но на практике компилятор может добавить несколько скрытых байт, и тот же набор полей внезапно займет уже 32 байта. Все дело в выравнивании и пустых вставках между полями.


Как процессор читает память:

Процессор не работает с байтами по одному. Ему удобнее читать данные блоками, размер которых зависит от архитектуры. На 64-битных системах это обычно 8 байт. И важное условие: адрес, по которому лежит значение, должен быть кратен размеру этого значения. Int должен начинаться с адреса, кратного 8. String в Swift занимает 16 байт, но его внутренняя структура такова, что он также требует выравнивания на 8 байт. Bool может лежать где угодно.

Компилятор об этом знает и автоматически добавляет пустые байты (padding) между полями, чтобы соблюсти выравнивание. Из-за этого порядок объявления полей влияет на итоговый размер структуры.


Два примера - два размера:

Возьмем структуру с тремя полями разных типов:


struct First {
let flag: Bool // 1 байт
let name: String // 16 байт
let count: Int. // 8 байт
}


Поля идут так: Bool (1 байт), затем String (16 байт), но чтобы String начался с адреса, кратного 8, компилятор добавляет 7 пустых байт после Bool. Затем идет Int (8 байт), который уже сам по себе выровнен. Сумма: 1 + 7 + 16 + 8 = 32 байта. Конечный адрес структуры тоже должен быть выровнен по максимальному требованию (8 байт), у нас он уже кратен 8 и остается без изменений.

А теперь поменяем порядок:


struct Second {
let name: String // 16 байт
let count: Int. // 8 байт
let flag: Bool // 1 байт
}


String и Int идут первыми - оба с правильным выравниванием, никакого padding между ними не нужно. Bool в конце занимает 1 байт. Итог: 16 + 8 + 1 = 25 байт. Но теперь конечный адрес структуры не кратен 8, поэтому компилятор добавит ещё 7 байт в конец, чтобы выровнять структуру в памяти. Финальный размер - 32 байта.

Вроде бы оба варианта дали 32 байта? Да, но если добавить еще одно маленькое поле, разница станет заметной:


struct Third {
let flag: Bool // 1 байт
let name: String // 16 байт
let flag2: Bool // 1 байт
let count: Int. // 8 байт
}


Здесь после первого Bool добавляется 7 байт padding, затем String, потом flag2 (1 байт) и перед Int снова нужно добавить 7 байт padding. Итого: 1 + 7 + 16 + 1 + 7 + 8 = 40 байт.

А если сгруппировать правильно:


struct Fourth {
let name: String // 16 байт
let count: Int. // 8 байт
let flag: Bool // 1 байт
let flag2: Bool // 1 байт
}


Все крупные поля идут в начале, мелкие - в конце. Padding нужен только в конце для выравнивания всей структуры: 16 + 8 + 1 + 1 = 26 байт, плюс 6 байт в конце = 32 байта. Экономия 8 байт на каждой структуре.


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

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

Кроме того, понимание выравнивания помогает при оптимизации: иногда достаточно просто переставить поля местами, чтобы структура похудела без потери функциональности. String, Int, Double требуют выравнивания по 8 байт, Bool и мелкие enum - по 1. Группируйте большие поля вместе, маленькие - в конец.


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍6🔥2🤯2👀2❤1
Forwarded from Кот Денисова
👨‍💻 От управления к хаосу: как плохой проджект подрывает продукт изнутри.

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


Системные ошибки непрофессионального проджекта:

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

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

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

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

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


Последствия для продукта:

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

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

🔹Сценарий 3: выгорание как норма: постоянные авралы, смещенные дедлайны и неблагодарность приводят к потере лучших специалистов. На их место приходят менее опытные, а качество падает еще сильнее.


Как отличить профессионала от дилетанта:

Профессиональный менеджер проекта:

🔹Говорит на языках всех участников процесса (бизнес, дизайн, разработка).

🔹Измеряет успех метриками продукта, а не отчетности.

🔹Создает психологически безопасную среду для экспериментов и ошибок.

🔹Защищает команду от внешнего хаоса и нереалистичных ожиданий.

🔹Принимает решения на данных, а не интуиции.

Непрофессионал:

🔹Использует жаргон и бюрократические процедуры как щит.

🔹Хвастается количеством проведенных митингов и созданных документов.

🔹Ищет виноватых вместо системных решений.

🔹Соглашается на все требования сверху без фильтрации.

🔹Работает в режиме постоянного кризис-менеджмента.


Что делать, если вы оказались в такой ситуации:

🔹Собирайте данные: фиксируйте, как решения ПМ влияют на скорость, качество и моральный дух команды.

🔹Говорите на языке бизнеса: покажите, сколько денег теряется из-за непрофессионального управления.

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

🔹Эскалируйте обоснованно: не жалуйтесь, а представляйте анализ проблемы с вариантами решений.


💡 Вывод:

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


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤9🔥3🙏1👀1🤝1
🔢 Swift Testing Agent Skill: правила написания качественных тестов с помощью ИИ.

Если вы активно используете агентов для генерации кода, то наверняка замечали: с тестами у них беда. Либо вообще не пишут, либо пишут так, что потом больно смотреть. Особенно когда дело доходит до Swift Testing - нового фреймворка от Apple, который пришел на смену XCTest. Чтобы не объяснять одно и то же каждый раз, появился готовый Agent Skill, который обучает ИИ правильно подходить к тестированию.


Что за зверь и зачем он нужен:

Swift Testing - это современный стандарт для написания тестов в Swift. Он более гибкий, мощный и лучше интегрируется с языком. Но агенты, если их не научить, часто допускают одни и те же ошибки: вешают @MainActor там, где не надо, добавляют serialized без причины, не используют параллельное выполнение.

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


Что внутри:

Репозиторий содержит не один файл, а целую библиотеку знаний, разбитую по темам:

🔹Основы: @Test, структура и нейминг.

🔹Ожидания и проверки: #expect, #require, обработка ошибок.

🔹Асинхронное тестирование: ожидание, продолжения, тестирование колбэков.

🔹Параметризованные тесты: одиночные и множественные аргументы, комбинации.

🔹Параллелизация и изоляция: как тесты работают по умолчанию, когда нужен serialized.

🔹Производительность и лучшие практики: как избежать flaky-тестов, сделать быстрее.

🔹Миграция с XCTest: как постепенно переходить, не ломая существующие тесты.

🔹Трейты и теги: фильтрация, условия, привязка к багам.

🔹Работа в Xcode: навигатор тестов, диагностика, отладка.


Как это работает:

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

Автор скилла применил его на реальном проекте и добился того, что тесты стали стабильнее и быстрее. А главное - агенты перестали совершать типовые ошибки вроде бесполезного добавления @MainActor, которое убивает параллельность.


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

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

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


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


💡 Вывод:

Агенты пишут код все лучше, но их все еще нужно учить хорошим практикам. Готовые скилл - это способ один раз настроить правила и забыть о правках вручную. Swift Testing Agent Skill закрывает важную нишу: тесты, которые не просто есть, а которые работают быстро и надежно. Если вы активно используете агентов в разработке, присмотритесь - это сэкономит вам часы нервотрепки и сделает тесты такими, какими они должны быть.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1814❤3🔥1🤔1🤝1
Привет! Хочу порекомендовать канал практикующего staff инженера из Т-Банка.

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

➡️ Подписывайтесь на @ios_broadcast
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
🔢 Декодирование JSON в Swift: работа с датой.

Одна из самых частых проблем при работе с API - даты. Казалось бы, что может пойти не так? Но на практике бэкенд может прислать timestamp, ISO-строку, американский формат или вообще что-то свое. Swift без правильной настройки просто упадет с ошибкой. Разбираемся, какие стратегии декодирования есть и когда что применять.


Что Swift делает по умолчанию:

Стандартная стратегия .deferredToDate работает только в одном случае: если данные были закодированы самим JSONEncoder в нативном для Apple формате. В реальной жизни такое встречается редко. Чаще всего сервер присылает либо Unix timestamp, либо строку в ISO 8601, либо что-то кастомное. И здесь без явного указания стратегии не обойтись.


Timestamp - секунды или миллисекунды:

Если API отдает число - скорее всего, это timestamp. Для секунд с 1970 года подходит .secondsSince1970, для миллисекунд - .millisecondsSince1970. Главное, чтобы бэкенд был последователен: если в одном поле миллисекунды, а в другом секунды - придется писать кастомную логику.


ISO 8601 - встроенная поддержка:

Для дат вроде "2025-11-01T12:00:00Z" есть готовая стратегия .iso8601. Но у нее есть нюанс: она довольно строгая. Если сервер пришлет миллисекунды или немного другой формат часового пояса, декодирование упадет. В таких случаях помогает кастомный ISO8601DateFormatter с ослабленными правилами.


Кастомный DateFormatter:

Когда формат не вписывается ни в одну стандартную стратегию, можно задать свой форматер:


let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)

decoder.dateDecodingStrategy = .formatted(formatter)


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


Когда форматов несколько:

Бывает, что API в разных полях или даже в одном поле присылает даты в разных форматах. Например, новые данные в ISO, старые - в timestamp. Или просто разработчики бэкенда не смогли договориться.

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


decoder.dateDecodingStrategy = .custom { decoder in
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)

let formatters: [DateFormatter] = [isoFormatter, legacyFormatter]

for formatter in formatters {
if let date = formatter.date(from: string) {
return date
}
}

throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "Неизвестный формат даты: \(string)"
)
}


Вся логика остается в одном месте, а не размазывается по моделям.


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍9🙏33🔥1🫡1
👣 Анонсирован Genkit для Dart: фреймворк для ИИ-приложений

Google анонсировала Genkit Dart - open-source фреймворк для создания полноценных ИИ-приложений на Dart и Flutter. Это не просто очередная обертка над API, а инструмент, который позволяет строить сложные ИИ-сценарии с типизацией, тестированием и удобным UI для отладки. Пока в предварительной версии, но уже выглядит многообещающе.


Что такое Genkit Dart и зачем он нужен:

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

🔵Единый API для работы с разными моделями (Google Gemini, OpenAI, Anthropic и другие совместимые).

🔵Строгая типизация ответов - никаких неожиданных форматов.

🔵Возможность писать логику один раз и запускать ее где угодно: на сервере, в облаке или прямо внутри Flutter-приложения.

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


Как это работает:

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


Все внутри Flutter (для прототипов):

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


Бэкенд + Flutter с общей типизацией:

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


Прокси-сервер для моделей:

Компромиссный вариант: на сервере поднимается тонкая прослойка, которая проксирует запросы к ИИ-моделям, добавляя авторизацию и валидацию. Ключи API хранятся на сервере, а Flutter-приложение общается с ним как с обычным Genkit-клиентом.


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


💡 Вывод:

Genkit Dart - это попытка внести порядок в хаос ИИ-разработки. Вместо того чтобы каждый раз городить свои обертки над моделями, можно взять готовый фреймворк с типизацией, тестируемостью и удобным UI. Пока это превью, но направление выглядит правильным. Если вы работаете с Dart/Flutter и думаете, как добавить в проект ИИ-фичи - присмотритесь.


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍6❤2🙏1👀1
🔢 Структура SwiftUI-проекта, которая не разваливается с ростом.

Стандартная структура от Xcode - это ловушка. ContentView.swift, пара папок, и вот уже через три месяца вы не можете найти, где лежит экран настроек, потому что он затерялся среди 50 других файлов в одной куче. Чтобы проект жил долго и счастливо, нужна система. И желательно с первого дня.


Главная ошибка - группировка по типам:

Самое популярное, но неудачное решение: папки Views, Models, ViewModels. Вроде логично, но когда в Views оказывается 40 файлов, а в Models - 20, вы начинаете тратить время на поиск. Хуже того, связанные сущности разбросаны по разным местам. Чтобы понять, как работает авторизация, нужно открыть три папки и собрать пазл.


Фичевая организация - спасательный круг:

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


Что вынести за пределы фич:

Не все должно жить внутри фич. Есть вещи, которые используются по всему приложению:

🔵Core: сеть, хранилище, базовые сервисы. Один экземпляр на все приложение, инициализируется один раз.

🔵UI Components: переиспользуемые кнопки, поля ввода, лоадеры. Чтобы не писать один и тот же стиль в каждом экране.

🔵Theme: цвета, шрифты, отступы. Единое место, где живет дизайн-система.

🔵Extensions: полезные расширения для стандартных типов.

🔵Resources: ассеты, локализация, шрифты.


ViewModel с человеческим лицом:

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

🔵@MainActor - чтобы не думать о потоках при обновлении UI.

🔵private(set) для публикуемых свойств - никто не должен менять состояние извне.

🔵Зависимости через инициализатор - чтобы можно было подменить их в тестах.

🔵Методы, которые четко отражают действия пользователя.


Навигация без боли:

Для простых приложений хватает встроенного NavigationStack с navigationDestination. Когда экранов становится много, стоит задуматься о координаторе. Один класс, который управляет всей навигацией в приложении - это сильно упрощает жизнь, особенно когда нужно передавать данные между экранами или обрабатывать диплинки.


Главное - последовательность:

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


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


💡 Вывод:

Организация проекта - это не про «красивую структуру», а про скорость разработки и стоимость поддержки. Когда на поиск нужного файла уходит 10 секунд вместо 5 минут, когда новая фича не ломает старую, когда код понятен даже тем, кто видит его впервые - это и есть правильная архитектура. А начинается она с правильной структуры папок.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
21👍8🔥3🗿2🙏1
🔨 Подключаем Cursor и Claude Code к Xcode 26.3

Apple открыла Xcode для внешних инструментов. В версии 26.3 появился MCP-сервер, который позволяет подключаться к проекту из Cursor, Claude CLI и любых других клиентов, поддерживающих этот протокол. Теперь можно отдавать команды на сборку, тестирование и даже рендеринг превью, не выходя из любимого редактора.


Как это работает:

Все строится вокруг утилиты xcrun mcpbridge. Это прослойка, которая принимает запросы по протоколу MCP и переводит их в XPC-вызовы для запущенного Xcode. Сам Xcode должен быть открыт с проектом - без этого ничего работать не будет.

Настройка занимает минуту. В настройках Xcode (Intelligence -> Model Context Protocol) нужно включить тумблер Xcode Tools. После этого можно подключать клиентов.


Claude Code и Codex CLI:

Для официальных CLI-инструментов Apple дает готовые команды:


claude mcp add --transport stdio xcode -- xcrun mcpbridge
codex mcp add xcode -- xcrun mcpbridge


После этого можно проверить список доступных инструментов через claude mcp list.


Cursor и другие редакторы:

В Cursor добавить интеграцию можно тремя способами. Через настройки -> Features -> MCP, добавить новый сервер с типом stdio и командой xcrun mcpbridge. Либо прописать конфиг вручную в ~/.cursor/mcp.json.

При первом подключении Xcode запросит разрешение. Нужно нажать Allow и можно работать.


Что умеют инструменты:

Через MCP-сервер открывается доступ к двадцати с лишним функциям Xcode:

🔹Чтение, запись, редактирование файлов прямо в проекте.

🔹Поиск по файлам и содержимому.

🔹Сборка проекта и получение логов.

🔹Запуск всех или выбранных тестов.

🔹Просмотр ошибок и предупреждений.

🔹Выполнение фрагментов кода в REPL-режиме.

🔹Поиск по документации Apple и расшифровкам WWDC.

🔹Рендеринг SwiftUI-превью в изображения.

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


Как агент понимает, с чем работать:

Большинство команд требуют указать, с каким окном Xcode работать. Агент сам вызывает XcodeListWindows, получает идентификатор вкладки и использует его в последующих вызовах. Например, на команду «собери проект» он сначала определит открытый проект, а потом запустит сборку.


Что важно знать:

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

Если нужно принудительно указать, к какому процессу Xcode подключаться, можно передать PID через переменную окружения MCP_XCODE_PID. Это может пригодиться, если запущено несколько копий Xcode.


Для продвинутых пользователей:

В папках ~/Library/Developer/Xcode/CodingAssistant/ лежат конфиги для встроенных агентов Codex и Claude. Там можно менять настройки, если хочется кастомизировать их поведение.


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥10❤3🙏3🗿11
This media is not supported in your browser
VIEW IN TELEGRAM
🔢 SwiftUI: плавный переход от кнопки к sheet.

С выходом iOS 26 и Liquid Glass компания Apple добавила не только новый стиль, но и новые анимации переходов. Одна из самых заметных мелочей - морфинг листа (sheet) из кнопки, которая его вызывает. Вместо стандартного выезда снизу кнопка буквально превращается в модальное окно. Выглядит эффектно и требует совсем немного строк кода.


Как это работает:

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


Все, что нужно - три простых шага:

🔵Создать namespace для анимации.

🔵Повесить на кнопку модификатор .matchedTransitionSource с уникальным ID.

🔵Добавить на лист .navigationTransition(.zoom(...)) с тем же ID и namespace.

@Namespace private var animation

Button("Выбрать дату") { showSheet = true }
.matchedTransitionSource(id: "datePicker", in: animation)
.sheet(isPresented: $showSheet) {
DatePickerView()
.navigationTransition(.zoom(sourceID: "datePicker", in: animation))
}



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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍11🔥3❤1🙏1👀1
Forwarded from Кот Денисова
👨‍💻 Когда вакансий меньше, а требований больше: стратегия выживания в ИТ.

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


Что на самом деле происходит:

Проблема не в том, что ИТ стал ненужным. Проблема в том, что изменился тип спроса. Раньше компании массово нанимали «на рост», создавая команды с запасом. Сегодня каждый найм - это точечное закрытие конкретной болевой точки. Отсюда парадоксальные, на первый взгляд, тренды:

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

🔹 ИИ не забирает работу: он меняет ее порог входа. Автоматизация рутинного кодинга и первичного скрининга резюме не означает конец профессии. Это означает, что ценность базового навыка написания кода падает. Ценность навыка решения сложных, нестандартных проблем - взлетает. Если ваша работа сводилась к переводу ТЗ в код, вы в зоне риска.

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

🔹Сильный техлид/архитектор, который может привести команду к результату.

🔹Автономный senior-разработчик, который сам ведет фичу от идеи до продакшена.


Новая система координат - что оценивают теперь:

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

🔹 Эффективность, а не занятость. Не «я работал в компании X 3 года», а «я спроектировал и внедрил систему кэширования, которая снизила p95-латентность API с 2с до 200мс и сэкономила X на инфраструктуре».

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

🔹 Скорость обучения и адаптации. Технологический стек устаревает быстрее. Ценится не знание конкретного фреймворка, а способность за 2-3 недели глубоко погрузиться в новую для себя технологию или домен и начать приносить пользу.


Тактика выживания и роста в новых условиях:

Стратегия «просто продолжать хорошо делать свою работу» больше не работает. Нужна активная позиция.

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

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

🔹 Сдвигайтесь в сторону продуктового мышления. Перестаньте быть просто «исполнителем задач». Начинайте задавать вопросы: «Какую пользовательскую проблему мы решаем?», «Как мы измерим успех этой фичи?». Разработчики, которые мыслят как мини-продакт-менеджеры, становятся незаменимыми.

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


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


💡 Вывод:

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


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍10🗿3🔥1🙏1👀1
🔢 Миграция в SwiftData: как обновлять модель без потери пользовательских данных.

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


Версионирование с первого дня:

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

Обычно схемам дают номера версий: V1, V2, V3. В коде они живут как отдельные enum со списком моделей и идентификатором версии. А для удобства в основном коде используют typealias, чтобы каждый раз не писать ExerciseSchemaV5.Exercise.

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


Когда SwiftData справляется сама:

Есть изменения, которые SwiftData умеет обрабатывать автоматически. К ним относятся:

🔵Добавление опционального поля (старым объектам просто ставится nil).

🔵Удаление поля (данные теряются, но миграция проходит гладко).

🔵Переименование поля (если указать @Attribute(originalName:)).

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


Когда нужна ручная работа:

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

В таких случаях пишется SchemaMigrationPlan с кастомными этапами. У каждого этапа есть две фазы:

🔵willMigrate - выполняется до применения новой схемы, работает со старыми данными (можно почистить дубликаты).

🔵didMigrate - после применения, здесь уже доступны новые модели и можно заполнять поля.

Например, если в новой версии появилось обязательное поле createdAt, в didMigrate проходим по всем объектам и проставляем дату.


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍7❤3🔥1🤝1
👨‍💻 Почему Apple давит на приложения для генерации кода.

Сначала Apple добавила в Xcode поддержку ИИ-агентов. А теперь тихо блокирует обновления приложений вроде Replit и Vibecode - тех самых, где можно собрать приложение по описанию на естественном языке. Формальная причина - нарушение правил App Store. Но реальная подоплека глубже.


Что происходит:

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

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


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

Вайб-кодинг приложения снижают порог входа в разработку. Они позволяют людям без знания кода создавать веб-сервисы, инструменты, а теперь и приложения для устройств Apple. Это напрямую конкурирует с Xcode и что более важно, с самим App Store.

Если приложение можно собрать в Replit и запустить на устройстве в обход стора - экосистема теряет контроль. Apple теряет комиссию. И, возможно, контроль над тем, что вообще появляется на устройствах пользователей.


Аргументирует Apple:


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

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


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17👀7❤3🤯1💯1🗿1
🍎 Apple объявила дату проведения WWDC 2026.

Компания официально анонсировала дату проведения WWDC 2026. В этом году мероприятие будет проходить с 8 по 12 июня.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17❤8👍2👏1🙏1
👨‍💻 Liquid Glass станет обязательным: Apple отключит ключ UIDesignRequiresCompatibility в iOS 27.

На этой неделе завирусилась новость: Apple сделает Liquid Glass обязательным в iOS 27, а ключ UIDesignRequiresCompatibility, позволяющий пока использовать старый дизайн, отключат. Источник один - пост в сети X, где говорится о сроке в апреле 2027 года. Apple официально не подтверждала эту новость, но на странице документации самого ключа четко указано, что он предназначен для временного использования - чтобы дать разработчикам время адаптировать приложения, а не для того, чтобы разработчики бесконечно откладывали переход на Liquid Glass.


Что делает данный ключ:

UIDesignRequiresCompatibility появился в iOS 26, чтобы дать разработчикам время адаптировать приложения под Liquid Glass. В документации Apple прямо указано: этот ключ - временное решение для тех, кто еще не успел обновиться. Не для тех, кому не нравится новый дизайн, а именно для тех, кто в процессе адаптации.

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


Что будет дальше:

Сейчас никаких официальных сроков нет. Пост в X - не официальное заявление. Но логика подсказывает, что ключ не будет жить вечно. Возможно, его отключат когда iOS 27 SDK станет обязательным при сборке и публикации приложений (предположительно в апреле 2027 года), возможно, раньше. Apple может в любой момент объявить дату, после которой приложения с этим ключом больше не будут приниматься в App Store.

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


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


💡 Вывод:

Новость о том, что ключ UIDesignRequiresCompatibility отключат, пока не подтверждена официально. Но факт остается фактом: он временный. И если вы его используете, вы просто откладываете неизбежное. Адаптация под Liquid Glass - это не вопрос «надо или не надо?», а вопрос «когда?». Лучше запланировать эту работу сейчас, чем потом в авральном режиме исправлять приложение под новые требования.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤17👍9🙏3🤝2💯1👀1🗿1
🏋️ Установка APK на Android усложняется: придется ждать сутки

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

Это касается не только нативных разработчиков, но и разработчиков на Flutter, которые собирают приложения под Android и которые распространяют свои приложения в обход Google Play (например через сайты, соц. сети или телеграм). Это означает, что привычный способ «включил неизвестные источники -> установил» больше не сработает. Вместо этого - сутки ожидания, биометрия и подтверждение, что вас никто не принуждает.


Что изменится:

Раньше достаточно было включить разрешение на установку из неизвестных источников и можно было ставить любой APK. Теперь нужно будет пройти целую процедуру:

🔵Включить режим разработчика.

🔵Подтвердить, что вас никто не принуждает.

🔵Перезагрузить телефон.

🔵Подождать сутки.

🔵Пройти биометрическую проверку.

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


Почему ввели данный процесс:

Google объясняет это борьбой с мошенниками. По статистике Global Anti-Scam Alliance, 57% взрослых сталкивались с мошенничеством за последний год, а ущерб составил 442 миллиарда долларов. Мошенники часто давят на жертв по телефону, заставляя прямо сейчас отключить защиту и установить вредоносное приложение. Принудительная пауза в сутки должна сломать эту схему.

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


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


💡 Вывод:

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


➡️ Flutter & Dart | Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🫡13👍6🤯3❤1🔥1👀1🗿1
🔢 Drag & Drop в SwiftUI: создаем перетаскиваемые элементы.

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


Что происходит на самом деле:

Когда вы начинаете тащить элемент, SwiftUI не перемещает визуальную копию по экрану. Он упаковывает данные в специальный контейнер NSItemProvider, описывает их тип через UTType (например `public.json`) и только тогда система понимает, что происходит.

По сути, это конвейер: объект -> JSON -> NSItemProvider -> передача -> JSON -> объект. Пока вы тащите палец по экрану, данные еще не переехали. Они начнут передаваться только в момент, когда вы отпустите палец.


Как сделать элемент перетаскиваемым:

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


struct TaskItem: Identifiable, Codable {
let id = UUID()
let title: String
let priority: Int
}


Теперь сделаем сам элемент перетаскиваемым. Ключевой момент - зарегистрировать данные в NSItemProvider и указать, что мы передаем JSON:


struct DraggableTaskView: View {
let task: TaskItem

var body: some View {
HStack {
Text(task.title)
Text("\(task.priority)")
.font(.caption)
}
.padding(12)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
.onDrag {
// 1. Кодируем задачу в JSON
guard let data = try? JSONEncoder().encode(task) else {
return NSItemProvider()
}

// 2. Создаем провайдер и регистрируем данные
let provider = NSItemProvider()
provider.registerDataRepresentation(
forTypeIdentifier: UTType.json.identifier,
visibility: .all
) { completion in
completion(data, nil)
return nil
}
return provider
}
}
}



Как подготовить зону для приема:

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


struct TaskColumn: View {
@Binding var tasks: [TaskItem]
@State private var isDropTargeted = false

var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Активные задачи")
.font(.headline)

ForEach(tasks) { task in
DraggableTaskView(task: task)
}

if tasks.isEmpty {
Text("Перетащите задачи сюда")
.foregroundColor(.gray)
.padding()
}
}
.padding()
.frame(minWidth: 250, minHeight: 300)
.background(
RoundedRectangle(cornerRadius: 16)
.fill(isDropTargeted ? Color.green.opacity(0.15) : Color.gray.opacity(0.1))
.overlay(
RoundedRectangle(cornerRadius: 16)
.stroke(isDropTargeted ? Color.green : Color.gray, lineWidth: isDropTargeted ? 2 : 1)
)
)
.onDrop(of: [.json], isTargeted: $isDropTargeted) { providers, location in
guard let provider = providers.first else { return false }

provider.loadDataRepresentation(forTypeIdentifier: UTType.json.identifier) { data, error in
guard let data = data,
let newTask = try? JSONDecoder().decode(TaskItem.self, from: data) else {
return
}

DispatchQueue.main.async {
tasks.append(newTask)
}
}
return true
}
}
}



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


💡 Вывод:

Drag & Drop в SwiftUI - это не магия, а четкий контракт: источник упаковывает данные, приемник распаковывает. NSItemProvider берет на себя передачу даже между разными приложениями, а UTType помогает системе не путать, что именно перемещается. Пользователь видит плавное перемещение, а разработчик - чистую архитектуру, где перемещаются данные, а не вьюхи.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍9❤4🔥3🙏1
Forwarded from Кот Денисова
👨‍💻 Карьера в ИТ: как понять, что пора расти дальше?

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

Как определить, что это действительно так и пора расти дальше? Есть несколько четких признаков, которые помогут это понять:

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

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

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


Что делать, если вы обнаружили эти признаки.

Не бегите к руководителю с требованием повышения. Подойдите с предложением.

🔹Неправильно: «Почему я еще не сеньор?»

🔹Правильно: «Я хочу расти до позиции сеньора. Давай обсудим, каких конкретных навыков и результатов мне не хватает? Можем составить план?»


Рост - это не только новая должность. Это часто и новые технологии.

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

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

🔹Внедряйте постепенно. Найдите в текущем проекте место для нового стека, например небольшой внутренний инструмент, виджет, перепишите несложный экран. Это даст вам кейс с формулировкой «опыт внедрения в реальном проекте».

🔹Фиксируйте достижения. обновите резюме в hh.ru, LinkedIn и других сервисах по поиску работы. Добавьте пункт об опыте работы с новым стеком, даже если это пет-проект. Это честно и убедительно.


Не забывайте о фундаменте, который не устаревает.

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

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

🔹Архитектурные принципы (SOLID, композиция): это основа для создания кода, который будет легко поддерживать и масштабировать даже через годы.

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


💡 Вывод:

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


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍8👏2🗿2🙏1
👨‍💻 App Store Connect обновили: 100 новых метрик для разработчиков.

Apple объявила о крупнейшем обновлении аналитики в App Store Connect с момента запуска. Теперь разработчикам доступно более 100 новых метрик, которые позволяют детально анализировать монетизацию, подписки и поведение пользователей. Старые отчеты постепенно уходят в прошлое - стандартные панели перестанут работать уже в середине этого года.


Что нового:

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


Ключевые изменения:

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

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

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

🔵Два новых отчета по подпискам с возможностью экспорта через API - можно интегрировать с внутренними системами и проводить офлайн-анализ.

🔵Расширенная фильтрация. До семи параметров одновременно, что позволяет глубже погружаться в данные.


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


💡 Вывод:

Для тех, кто монетизирует приложения через подписки или внутриигровые покупки, обновление App Store Connect - значимый шаг. Раньше полноценная аналитика была доступна только через платные сторонние сервисы. Теперь Apple дает аналогичные инструменты бесплатно и данные основаны на реальных цифрах, а не на оценках. Это делает анализ эффективности приложения более точным и прозрачным. Остается только разобраться в новых метриках, понять, как их правильно интерпретировать и грамотно использовать.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍8❤3🙏1🤝1
👨‍💻 Минцифры отключает единственный удобный способ оплаты подписки Apple Developer для разработчиков под экосистему Apple.

С 1 апреля в России отключается оплата сервисов Apple со счета мобильного телефона. Минцифры дало указание мобильным операторам отключить эту возможность. Официальная причина - принудить Apple вернуть удаленные российские приложения в App Store.


Кого это коснется:

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

Технически есть альтернатива - подарочные карты (Apple Gift Cards). Но это неудобно: карты продаются на сторонних сайтах с наценкой и нет никакой гарантии, что код не был активирован до вас. Кроме того, это потребует лишних действий по поиску сервиса/посредника, у которого можно приобрести подарочные карты. Через мобильный счет было проще, быстрее и безопаснее.

Без действующей подписки Apple Developer невозможно размещать приложения в App Store. Нельзя выпустить пет-проект, нельзя опубликовать тестовое приложение, нельзя даже просто зарегистрироваться как разработчик, если вы не готовы возиться с обходными путями. Если же разработчик уже разместили свое приложение, то без активной подписки оно будет снято с публикации.


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


💡 Вывод:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
💯16🤯10🫡3🔥2👀1🗿1
🔢 Swift 6.3: официальный SDK для Android и новый атрибут @c

Вышел Swift 6.3 - релиз, который делает акцент на том, чтобы язык работал не только на Apple-платформах. Android, C / C++ интеграция, улучшенная сборка и поддержка встраиваемых систем - вот главные темы этого обновления.


Главное нововведение - @c

Самый интересный атрибут в этом релизе - @c. Он позволяет экспортировать Swift-функции и перечисления в C-заголовки. То есть вы можете написать функцию на Swift и вызывать ее из C или C++ кода. Без лишних прослоек, без ручного написания оберток.

Особенно это актуально для библиотек, которые работают с LLM - большинство из них написаны на C / C++, а все остальное - обертки. Если у вас есть своя обертка над llama.cpp, теперь ее можно сделать более прямой и эффективной.

Также @c работает в паре с @implementation: можно объявить функцию в C-заголовке, а реализовать ее на Swift. Компилятор проверит, что сигнатуры совпадают, и сгенерирует все необходимое.


Модульные селекторы и контроль оптимизаций:

Другая полезная фича - модульные селекторы. Если в двух импортированных модулях есть функции с одинаковыми именами, раньше приходилось изворачиваться. Теперь можно явно указать: ModuleA::getValue() и ModuleB::getValue(). Конфликтов больше нет.

Для библиотек добавили новые атрибуты: @specialize (прекомпилированные версии generic-функций), @inline(always) (гарантированное встраивание) и @export(implementation) (экспорт реализации для оптимизаций). Это для тех случаев, когда нужно выжать максимум производительности.


SwiftPM и Swift Build:

Менеджер пакетов получил preview-версию нового движка сборки Swift Build. Он делает сборку более единообразной на всех платформах. Теперь не должно быть ситуаций, когда пакет собирается на macOS, но падает на Linux из-за различий в тулчейне.


Android и Embedded:

В релизе появился официальный Swift SDK для Android. Это большой шаг для кроссплатформенной разработки на Swift. Можно писать нативные программы для Android, обновлять существующие пакеты, чтобы они собирались под Android, и интегрировать Swift-код в существующие приложения на Kotlin / Java.

Embedded Swift тоже получил улучшения: отладка, линковка, интероп с C - все это стало стабильнее.


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


💡 Вывод:

Swift 6.3 - это не про очередные фичи для iOS-разработки. Это про то, чтобы Swift стал языком, на котором можно писать везде: от встраиваемых систем до Android-приложений. C-интероп через @c открывает прямой доступ к огромной экосистеме библиотек. А улучшения в SwiftPM и Swift Testing делают разработку более предсказуемой. Для тех, кто пишет кроссплатформенный код или работает с низкоуровневыми библиотеками, этот релиз - важный шаг вперед.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍12🔥4❤2🙏1🫡1
👣 Как Dart и Flutter смотрят на ИИ в 2026 году

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


Цифры, которые объясняют все:

Согласно опросам, 84% разработчиков в целом используют ИИ-инструменты в своей работе. Среди Flutter-разработчиков этот показатель чуть ниже - 79%, но все равно впечатляет. Однако есть проблема: 46% не доверяют точности ИИ при решении критических задач. Это тратит лишнее время на проверку сгенерированного кода.


Главные принципы:

Команда декларирует несколько ключевых правил, которым следует при развитии ИИ-направления:

🔵Человек прежде всего. Dart остается языком, который легко читать и поддерживать человеку, даже если код написан ИИ. Это важно, потому что ИИ-сгенерированный код не должен превращаться в нечитаемую кашу.

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

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

🔵Доверие через качество. Главная проблема ИИ-генерации - затраты времени на проверку. Команда работает над тем, чтобы сгенерированный код был точным, идиоматичным и соответствовал стандартам проекта. Для этого сотрудничают с Google Deepmind и Antigravity по оценке моделей.


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


💡 Вывод:

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


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