iOS Broadcast
3.47K subscribers
1.91K photos
86 videos
1.06K links
Подборка новостей и статей для iOS разработчиков.

Новости Kotlin и мультиплатформы @kotlin_broadcast
Новости Android @android_broadcast
Реклама и прочее @ab_manager
Download Telegram
🈸 StoreKit 2: как давать доступ к premium-фичам (и не сломать уровни подписки)
Не часто приходится работать с in-app-ми и это то место, в котором не хочется допускать ошибки. Тут и репутационные и финансовые риски. Особенно сложно работать с нескольими уровнями подписок: как только вы добавляете несколько тарифов (например, личный / семкйный + месяц / год), появляются типичные боли:
🔵Приложение не понимает “какой план активен”, когда есть overlap при апгрейде/даунгрейде
🔵UI не может честно показать “что сейчас” и “на что продлится”
🔵Транзакции прилетают повторно / entitlement “откатывается” после рестарта

Подход из статьи: “всегда выбираем самый высокий tier”
1) Группы подписок + уровни (Level of Service)
Apple использует “Subscription Level” (lower number = *higher tier*) для логики апгрейдов/даунгрейдов и того, какая подписка должна считаться активной
В примере:
🟢Family = level 1 (выше)
🟢Individual = level 2 (ниже)
🟢Monthly и Yearly одного тира должны иметь одинаковый level, чтобы это был тот же tier, другая периодичность.

2) Модель тиров в коде
Делаем enum PassStatus (notSubscribed / individual / family) и маппим productID → tier, чтобы интерпретировать статусы StoreKit

3) Вычисляем текущий доступ по status’ам
Фильтруем statuses до .subscribed и выбираем max tier (чтобы Family “перебивал” Individual при overlap)

4) Trust only verified
Только .verified транзакции считаем entitlement’ом. Если verification не прошёл — считаем “нет подписки”.

5) Обязательно finish + наблюдаем апдейты
🟢Каждую verified транзакцию нужно finish(), иначе StoreKit может принести её снова
🟢На старте проверяем Transaction.unfinished (после крэша/сети)
🟢Держим живым listener на Transaction.updates для мгновенного обновления UI

6) UI: SubscriptionStoreView + статус рядом
В статье используют SubscriptionStoreView(groupID:), а текущий tier и “renews to …” строят из renewalInfo.

Эмпирическое правило для подписок
🟢Entitlement = verified transaction + правильно настроенный tier
🟢Тарифы = данные (ASC/StoreKit config), код должен лишь корректно их интерпретировать
🟢UI всегда показывает “effective tier”, а не последний купленный productID
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
📱 SwiftUI: как комбинировать жесты без магии и багов
Немного базы в пятницу, статья про жесты в SwiftUI.

Кейс один экран — несколько интеракций
Как только на элементе появляются drag + rotate + long press + tap — SwiftUI быстро начинает угадывать, какой жест вы имели в виду и не всегда у него это выходит успешно:
🔵Случайные конфликты распознавания
🔵Съеденные жесты
🔵Неочевидное поведение (особенно на трекпаде)
Все это создает негативный UX

🔴Искушение: повесить несколько .gesture(...) и надеяться... На что-то обычно заканчивается тем, что один жест побеждает всегда, а второй почти не срабатывает.

Три базовых композиции жестов в SwiftUI:

1️⃣In sequence — сначала один, потом второй
Кейс: long press → drag
Используем LongPressGesture(...).sequenced(before: DragGesture())
🔵сначала удержание (например 0.5s)
🔵если пользователь продолжает — начинается drag
Идея: @GestureState обновляется через .updating(), а drag-translation читаем в .onChanged() на втором этапе

2️⃣ Simultaneous — два жеста одновременно
Кейс: drag + rotate
DragGesture().simultaneously(with: RotateGesture())
🔵можно тащить и одновременно крутить (двумя пальцами)
🔵каждый жест обновляет своё состояние через .onChanged()

3️⃣ Exclusive — либо одно, либо другое
Кейс: tap vs long press
ExclusiveGesture(TapGesture(), LongPressGesture(minimumDuration: 1.0))
🔵сработает первый распознанный жест
🔵tap меняет цвет, long press — увеличивает scale

💡 Шпаргалка:
🔵Если жесты должны идти “как сценарий” → Sequence
🔵Если жесты независимы и должны работать параллельно → Simultaneous
🔵Если жесты конкурируют за одно и то же взаимодействие → Exclusive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🐚 Skip - плагин Xcode для транспиляции SwiftUI приложения на Android теперь Open Source
Я вам несколько раз рассказывал про Skip и о своих надеждах и сомнениях по поводу этого инструмента и пришли новости. Платно получать лок на вендора желающих достаточно не оказалось, но наработки пригодились Apple рабочей группе по Android.

📱 Проблема: cross-platform “без компромиссов” всегда упирался в доверие
Многие команды хотят Swift/SwiftUI → Android, но боятся строить стратегию на маленьком закрытом платном туле: “а если завтра rug pull / покупка / закрытие?”. Skip прямо называет этот страх ключевым барьером adoption.

Начиная с Skip 1.7:
🟢убраны все лицензии: никаких ключей, EULA, trial/period
🟢open-sourced “skipstone” — движок, который делает всю магию на build-time (плагины Xcode/SwiftPM, трансформация iOS→Android, bundling ресурсов/локализаций, JNI bridge, transpile, packaging, export)
🟢документация/сайт переезжают на skip.dev, тоже open source

Моя оценка Skip в 2026:
🔵 Если вам нужен shared Swift-стек (и вы готовы жить в мире “не все либы заведутся идеально с первого раза”) — Skip теперь реально стоит POC
🔵 Главный риск (закрытый платный core) — существенно снижен: foundation теперь открытый и бесплатный
🔴 Главный вопрос, а нужен ли он в мире с AI агентами, когда можно попросить создать нативное приложение под Android на основе исходников для iOS, пробовал кто-то?
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔6👍32🔥1
🎹 Liquid Glass «по-взрослому»: что делать, когда режим совместимости исчезнет
iOS 26 принёс Liquid Glass как новый визуальный слой системы. Первое время Apple дала “костыль” — compatibility mode, чтобы старый UI не «поплыл» сразу после перекомпиляции. Но ключевое слово тут — на первое время.

Когда перестаёт работать режим совместимости?
Сегодня (Xcode 26 / iOS 26) можно отложить новый дизайн через Info.plist ключ UIDesignRequiresCompatibility (UI Design Requires Compatibility). Donny Wals прямо пишет, что Apple планирует убрать эту опцию в следующем мажорном Xcode, и поэтому Xcode 27 вероятно сделает Liquid Glass обязательным

Дополнительно, на форумах Apple в обсуждениях этого ключа фигурирует предупреждение из документации:
Temporarily use this key while reviewing and refining your app’s UI for the design in the latest SDKs


То есть ставка на “оставим compat mode навсегда” — плохой план.
И ещё момент: compatibility mode уже может ломать поведение контролов (пример — баг с UISegmentedControl, который проявляется именно при включённом UIDesignRequiresCompatibility)

Стратегия миграции без боли:
🟢Dev-схема: Liquid Glass включён (без UIDesignRequiresCompatibility)
🟢Release-схема: compat mode включён пока мигрируете
🟢Как только готовы — убираете ключ и закрываете тему
Самый простой вариант — две Info.plist: Info-Dev.plist и Info-Release.plist, и переключение в Build Settings.

Начинайте не с карточек/экраников, а с того, что пользователь видит всегда:
🟢Tab Bar / Tool Bar / Navigation Bar
🟢Search / Large titles
🟢Sheets / Popovers / Alerts
🟢Scroll edge / Underlap / Safe areas
Цель: чтобы приложение выглядело органично *в рамках нового system look* — даже если ваш контент ещё не идеален.

Liquid Glass любит:
🟣слои
🟣прозрачность
🟣динамический фон

А ломает:
🔴мелкий текст на blur
🔴тонкие разделители
🔴кастомные цвета без учета системных материалов

Правило: переходите на системные семантические цвета/материалы там, где можно, а кастом оставляйте для контента.

Accessibility — обязательный прогон
🟡Reduce Transparency (особенно важно для “стекла”)
🟡Reduce Motion
🟡Dynamic Type (XL–AX)
🟡Increased Contrast / Bold Text
Иначе вы сделаете красиво, но сломаете читаемость для части пользователей.

⚠️ Когда Xcode 27 уберёт opt-out, останется два пути:

1. Принять Liquid Glass как новый baseline
🟢системные компоненты → выглядят по-новому
🟢ваш бренд → через контент, типографику, иллюстрации, spacing
🟢кастомный “старый iOS” не симулируете, иначе будете выглядеть “как чужой app”
Это путь с минимальными затратами и максимальной совместимостью.

2. Сделать свои компоненты
🟡вы пишете/поддерживаете кастомные компоненты (tab bar, nav bar, backgrounds)
🟡постоянно догоняете изменения системы
🟡рискуете UX/доступностью и конфликтами с платформенными паттернами
⚠️ Подходит только если у вас продукт, где дизайн — ключевой дифференциатор, и есть ресурс на поддержку.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52
🔨 Geko - CLI для инфраструктуры разработки в Xcode-проектах
Большой релиз инструмента, который мы активно используем у себя внутри для работы с приложениями.

Когда у вас сотни/тысячи модулей, вы начинаете страдать от обвязки:
🔵Генерация .xcodeproj/.xcworkspace становится медленной
🔵Сборка ползёт из-за отсутствия нормального кэша между модулями
🔵Зависимости (Pods/SPM) превращаются в отдельный мир боли
🔵Любые нестандартные кейсы требуют костылей/скриптов

Решение: Geko
Geko — CLI-утилита для управления dev-инфраструктурой Xcode-проектов: DSL на Swift для описания структуры, генерация проектов и встроенная система кэширования.
Что есть из коробки:
🟢Swift-DSL для описания структуры проекта
🟢быстрая генерация .xcodeproj/.xcworkspace даже для тысяч модулей
🟢Build Cache: локальный + удалённый (S3-совместимый)
🟢Встроенный пакетный менеджер для CocoaPods + поддержка SPM
🟢plugin system под сложные кейсы
🟢Частичная поддержка Linux (под subset фич)

⚡️ Кэш: топ фича из коробки:
🔵Локально — можно стартовать без доп настроек
🔵Профили прогрева
🔵Удалённый кэш (S3)
Please open Telegram to view this post
VIEW IN TELEGRAM
12
📱 Мигрируем на Observation в SwiftUI: как переехать без фантомных перерисовок
Проблема: ObservableObject + @Published слишком широковещательный. SwiftUI часто инвалидирует больше UI, чем нужно, потому что сигнал приходит как "объект изменился", а не "изменилось конкретное свойство".

Что даёт Observation
🟢Трекинг на уровне свойств: обновляются только вьюхи, которые реально читали изменившиеся поля
🟢Потенциально меньше лишних перерисовок и более предсказуемые апдейты

Миграция - это не только @Published -> var, а смена связки property wrappers и того, как модель прокидывается через SwiftUI.

Переезд по шагам:
1. Модель: ObservableObject -> @Observable
🟣Убираем ObservableObject
🟣Убираем @Published
🟣Ставим @Observable на модель
🟣Всё, что не должно участвовать в наблюдении (сервисы, зависимости) помечаем @ObservationIgnored

2. Владелец модели: @StateObject -> @State
🟣Модель с @Observable можно держать в @State, это нормальный паттерн в новой системе

3. Дочерние вьюхи: @ObservedObject -> @Bindable
🟣Если внутри дочерней вьюхи нужны биндинги к полям модели - используем @Bindable
🟣@Binding оставляем для value-параметров, @Bindable - для @Observable моделей

4. Глобальная модель: @EnvironmentObject -> @Environment(Model.self)
🟣Для внедрения через окружение используем @Environment(Model.self) вместо @EnvironmentObject

Где обычно ошибки
🔴Забыли @ObservationIgnored на сервисах -> неожиданные апдейты и лишние перерисовки
🔴Путают @Bindable и @Binding -> биндинги перестают работать так, как ожидали
🔴Нужны сайд-эффекты на изменение модели вне SwiftUI -> лучше явно трекать изменения, а не надеяться на onAppear/onChange

Observation - это не косметика. Это смена модели наблюдения: точнее апдейты, меньше шума, но важно правильно разнести @State, @Bindable и игнорируемые зависимости.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍2
🔨 Agentic Coding в Xcode 26.3
Официальное демо от Apple по интеграции агентов и MCP в Xcode, очень рад что Apple двигается в сторону сообщества а не только пилит свои модели. Xcode 26.3 получил поддержку агентов. Это не автодополнение и не чат в IDE, а режим, где агент может выполнять многошаговые задачи внутри проекта, пробовать собрать проект и самостоятельно анализировать ошибки и исправлять их.

Ключевая идея
🟡Вы формулируете цель (добавь фичу, поправь баг, сделай рефакторинг, добавь тесты)
🟡Агент сам разбивает задачу на шаги, ориентируется на архитектуру проекта и использует инструменты Xcode, чтобы довести до результата

Что конкретно умеет агент в Xcode 26.3:
🟢Писать и редактировать код в нескольких файлах
🟢Искать по проекту и исследовать структуру файлов
🟢Искать в документации и подтягивать контекст
🟢Обновлять настройки проекта (на уровне Xcode)
🟢Итеративно собирать проект, фиксить ошибки и повторять цикл
🟢Проверять визуальный результат через Xcode Previews и корректировать UI

При этом Xcode 26.3 открывает свои возможности через Model Context Protocol (MCP), то есть теоретически можно подключать совместимые инструменты/агентов

Почему это важно?
🟢IDE перестаёт быть редактором с подсказками и становится средой, где можно делегировать цепочку действий
🟢Самый заметный профит — в задачах “сверху вниз”: миграции, рефакторинги, настройка проекта, тесты, фиксы регрессий после SDK-апдейтов
🟢Меньше ручной навигации и контекст-переключений: агент живёт рядом с кодом и работает с проектом, а не с кусками текста

Кому зайдёт больше всего
🟢Командам с большими кодовыми базами и частыми релизами
🟢Тем, кто постоянно делает скучные задачки: обновить зависимости, поправить предупреждения, привести API к новым требованиям, написать тесты под изменения
🟢Тем, кто мигрирует UI под Liquid Glass или под новые требования App Store и не хочет тонуть в рутине

Xcode 26.3 делает следующий шаг: от подскажи строку к выполни задачу в проекте. И это выглядит как самый практичный апгрейд IDE-помощника за долгое время
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🔧 Я релижу код, который не читаю
Досмотрел сегодня увлекательное интервью Питера Стейнбергера. Это создатель PDF-фреймворк PSPDFKit который был невероятно популярным. История классического пути в iOS разработку - впервые увидел iPhone, впечатлился возможностями и создал приложения для iOS 2. После чего работа в Nokia, успех пет-проекта, выгорание и возрождение интереса к разработке с приходом AI. Мои хайлайты:

Развитие продукта
🔵Фокус на деталях, как у Apple позволил добиться успеха.
🔵Опыт в найме фрилансеров.
🔵Фокус на разработчиках и создание качественных материалов.
🔵Отказ от агрессивных маркетинговых стратегий.
🔵Распространение технологий на все платформы.
🔵Создание эталонного теста для WebAssembly, используемого Google, Microsoft и Apple.

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

Возвращение к работе
🔵Трудности перехода от нативной разработке к фулстек с вебом
🔵Опыт работы с облачным кодом и Google AI Studio.
🔵Генерация спецификации кода с помощью ИИ.
🔵Проблемы с надёжностью кода, сгенерированного ИИ.
🔵82% разработчиков считают, что ИИ ускоряет написание кода, но 96% не доверяют его точности.

Структура приложений
🔵Архитектура системы важнее понимания каждой строки кода.
🔵Автор использовал Cloud Code, Gemini 2.5 и Opus 4.
🔵Понимание архитектуры помогает различать правильное и неправильное.
🔵Летом AI по мнению автора перешел ту грань, когда можно создавать ПО без ручного написания кода.
🔵Codex лучше подходит для сложных приложений.
🔵Модель начинает с нуля, требуя советов от разработчика.
🔵Обсуждение вариантов и планирование вместе с агентом.
🔵Codex помогает в системном представлении продукта.
🔵Архитектор разрабатывает план системы, но не занимается практической деятельностью.
🔵Автор несёт полную ответственность за код.
🔵 Важны результаты и ощущения от продукта, а не детали реализации.
🔵Люди, любящие сложные задачи и алгоритмы, часто отвергают ИИ.
🔵Написание тестов часто утомительно, но важно для качества кода.
🔵Хорошая документация проекта может быть создана без написания тестов вручную.
🔵Модели ИИ помогают улучшать архитектуру через тестирование.
🔵Адаптация к работе с ИИ требует времени и усилий.
🔵Опытные инженеры должны уметь делегировать полномочия и понимать, над какими деталями работать.

Влияние ИИ на разработку ПО
🔵ИИ повышает продуктивность отдельных разработчиков, но требует пересмотра принципов работы компаний
🔵Необходимость людей с видением продукта и высокой компетенцией
🔵Возможные экономические риски и проблемы с трудоустройством в новом мире
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍2