Привет!
15 июля истёк срок, который ФАС дала Apple на предустановку RuStore и MAX. Требования не выполнены, дело возбуждено, потолок штрафа доходит до 4 млрд рублей. Ну, вроде очередной эпизод в переписке ведомства с корпорацией, таких за последние годы набралось много.
Но через пару дней я ко всей этой истории и понял, что смотрю на верхушку истории, которая тянется с 2022 года, а целиком я её не видел ни разу. Захотелось разложить всё в разрезе: что за эти четыре года случилось с мобильной разработкой в России. С продажами устройств, с доставкой приложений до живых людей, со стеком, с тем, где сейчас работа.
Скажу сразу: любимой платформы у меня тут нет, болеть ни за кого не собираюсь.
Доли платформ никто толком не знает
Самая цитируемая цифра — StatCounter. Май 2026: Android 58,5%, iOS 41,4%. Апрель того же года: Android 64,7%, iOS 35,1%.
Шесть процентных пунктов за месяц. Столько устройств физически не меняется за тридцать дней, так что дёрнулся не рынок, а методика: StatCounter считает просмотры страниц с установленным счётчиком, а не людей и не устройства. Один человек, весь вечер листающий ленту с айфона, весит здесь больше десяти зашедших с бюджетного андроида проверить баланс. Добавьте фильтрацию ботов и перекос выборки по сайтам.
Ну и ещё момент. Сорок процентов трафика дают не покупки, а телефоны, которые уже давно лежат у людей в карманах. Айфон дольше носят, чинят, потом отдают на вторичку, и с него банально больше сидят в интернете. Доля эта накопленная, а пополняется она из тех восьми процентов, что Apple продаёт сейчас. Старые телефоны ломаются и перестают тянуть новые приложения, а на замену человек берёт то, что стоит двадцать четыре тысячи, а не семьдесят. Кредит тут не спасает, он растягивает платёж, а не добавляет денег. Так что сорок процентов трафика говорят не о том, что iOS держится, а о том, что она живёт на старых покупках.
Строить на такой метрике карьерное решение — так себе идея.
Рынок сжался почти на пятую часть
По оценке Fplus и «М.Видео», в 2025 году в России продали 24,2 млн смартфонов на 588 млрд рублей против 29,8 млн на 720 млрд годом раньше.
Рынок смартфонов в России, 2024 против 2025
У МТС за тот же год другие числа: 23,6 млн штук и 574 млрд рублей. Расхождение в 600 тысяч устройств объясняется не ошибкой, а разными методиками. Кто-то видит федеральные сети, кто-то добавляет маркетплейсы, и почти никто не видит серый импорт, через который едет заметная часть айфонов. Так что абсолютные числа тут стоит держать в голове как порядок величины, не больше. Зато пропорции внутри одного источника надёжны, и вот они уже интересные.
Одна компания на пятом месте и на первом одновременно
Берём разбивку по брендам за 2025 год и смотрим дважды: в штуках и в деньгах.
Доли брендов в штуках и в деньгах
У Apple восемь процентов проданных смартфонов, пятое место позади Xiaomi, Samsung, Tecno и Realme. Каждый двенадцатый аппарат. И двадцать восемь процентов выручки рынка, первое место с отрывом. Xiaomi зеркально: 22% штук против 14% денег.
Откуда такой разрыв, видно по среднему чеку.
Средний чек: рынок против iPhone
Средний смартфон в России стоит около 24 тысяч рублей: это просто 588 млрд, поделённые на 24,2 млн. Средний iPhone около 70 тысяч.
Расхожая формула про охват у Android и деньги у iOS подтвердилась, и на ней я собирался закончить. Но решил всё-таки посмотреть, что происходит с приложениями на этих устройствах.
Из 165 банков в App Store осталось 37
Приложения российских банков начали убирать из App Store весной 2022 года, и с тех пор их туда не вернули. На июнь 2026 года из 165 крупнейших банков России в App Store доступны 37. В RuStore — 98.
Банки возвращаются под чужими именами: ВТБ в начале июня 2026 года выложил приложение «Сириус», замаскированное под таймер для работы по методу Pomodoro. Альфа-Банк за один только 2026 год выпускал «Холдер» под видом сервиса аренды ячеек, «Ключ» под видом сервиса для арендаторов жилья и «А-Интерьер», который на банк не похож вообще ничем. Модераторы App Store снимают их с публикации за несколько часов, так что скачать успевают не все.
Хуже всего приходится тем, у кого приложение уже стоит. Старый клиент ВТБ при запуске требует обновления, а обновиться неоткуда: в магазине его нет. Дальше человека ждёт выбор из трёх неудобных вариантов: веб-версия в Safari, установка через сотрудника банка в отделении или восстановление из истории покупок через iMazing на компьютере.
Отсюда вылезает третья ось, которой в разговорах про платформы обычно нет. Обсуждают две: сколько пользователей и сколько с них денег. А есть ещё вопрос, дойдет ли продукт до пользователя и сможет ли тот его обновлять — и по этому вопросу деньги в кармане аудитории не помогают, если дотянуться до неё нечем.
Июль 2026
В июне 2026 года из App Store пропали все сервисы VK. 16 июля приложения VK и мессенджер MAX исчезли ещё и из Google Play (при этом неизвестно, кто будет следующим). Событие одно, платформы две, дальше начинается расхождение.
На Android пользователи просто ушли в другой магазин: с 16 по 19 июля установки VK-приложений через RuStore и прочие сторы выросли более чем в полтора раза относительно предыдущей недели. На андроидах ничего трагичного не произошло, люди открыли тот же рустор и нажали «установить».
На iOS так сделать нельзя, поэтому там предложили веб-версию MAX. Семь миллионов человек прошли через инструкцию, потому что штатного пути не осталось.
Дело не в том, что Android лучше спроектирован или что Google добрее. Google в этой истории выпилил те же самые приложения. Дело в том, что на Android у продукта был запасной канал, а на iOS его не было.
Заодно снимается вопрос, не игрушечный ли этот запасной канал. Ежемесячная аудитория RuStore превысила 68 млн человек, в каталоге больше 110 тысяч приложений от разработчиков из семидесяти стран, а за первое полугодие 2026 года пользователи скачали оттуда больше 3 млрд раз.
Почему второго канала на iOS так и не появилось
7 июля 2025 года подписан закон о предустановке, с 1 сентября он вступил в силу: RuStore и MAX стали обязательны, в том числе на iOS. Закон запрещает производителю мешать сторонним магазинам работать — блокировать пуши, отключать автообновления, требовать, чтобы цены были не ниже, чем в App Store.

Прошёл почти год, и RuStore под iOS не существует. Чтобы он появился, Apple должна включить в системе механизм сторонней дистрибуции целиком. Механизм у неё есть, она включала его в Евросоюзе под DMA, в Японии и Бразилии — каждый раз под давлением закона и каждый раз в минимально возможном объёме. Вдобавок он завязан на регион пользователя, то есть под Россию пришлось бы поднимать всю юридическую и техническую обвязку отдельно, в стране, откуда компания официально ушла в 2022 году и куда все iPhone едут параллельным импортом.
Отсюда и финал июля: предупреждение ФАС, истёкший срок, возбуждённое дело. Сумма штрафа на фоне оборотов Apple смешная, и рассчитывать, что она что-то изменит, я бы не стал.
Второго канала на iOS в России нет, и закладываться на его скорое появление не надо.
Теперь то же самое, но глазами разработчика
До сих пор я смотрел сверху: доли, каналы, отчёты ритейла. Такая картина объясняет, почему двигаются компании, но про вашу рабочую неделю не говорит ничего. Поэтому дальше три вопроса, которые касаются уже лично вас: где лежит работа, сколько стоит вход со стороны Swift и чем Kotlin с ним расходится в живом коде.
Начну с работы, потому что вокруг неё крутится самое частое заблуждение. Когда говорят «рынок мобильной разработки», обычно держат в голове приложения из магазинов. Для Android это хорошо если половина истории.
Кассовые терминалы, складские ТСД, киоски самообслуживания, медицинское оборудование, промышленные планшеты — почти всё это работает на Android, часто в режиме киоска под управлением MDM. Рядом потребительская сторона: планшеты, телевизоры и приставки, часы, головные устройства в машинах.
Задачи там не похожи на продуктовую разработку. Интеграция с железом через USB и последовательные порты, работа без сети сутками, накатывание обновлений на парк устройств без участия пользователя, требования к аптайму, которых у обычного приложения нет. Для инженера это другой набор навыков.
Сам же Android держит примерно семь смартфонов из десяти в мире, и Kotlin остаётся для него языком по умолчанию, так что навык не заперт внутри российского контура и работает ровно так же в любой другой стране.
Порог входа упал сильнее, чем принято думать
Складывается картина: задач на Android больше, они разнообразнее, доставка до пользователя надёжнее. Логично спросить, сколько стоит туда зайти человеку со Swift за плечами.
Меньше, чем кажется. Google держится подхода Kotlin-first уже несколько лет, и карта переноса для swift-разработчика выглядит неприлично короткой: декларативный UI с состоянием ложится на Compose, async/await на корутины, Combine на Flow, протоколы с расширениями на интерфейсы и extension-функции, опциональность есть и там, и там.
Причём заходить целиком не обязательно. Kotlin Multiplatform стабилен с ноября 2023 года и официально поддержан Google для шаринга бизнес-логики между Android и iOS, а Compose Multiplatform для iOS стал стабильным в мае 2025 года в релизе 1.8.
Приятная картинка ломается в четырёх местах, собрал их в один кусок:
// ────────── 1. data class — ссылочный тип, а не значение ──────────data class Filter(val tags: MutableList<String>)val a = Filter(mutableListOf("new"))val b = a.copy()b.tags.add("sale")println(a.tags) // [new, sale] — список у копии тот же самый// Swift: struct Filter { var tags: [String] } напечатал бы ["new"],// потому что массив там значение с копированием при записи// ────────── 2. Платформенные типы: категория, которой в Swift нет ──────────val name: String = javaLibrary.getName()// на деле пришёл String! — Java без аннотаций, компилятор снял с себя проверку.// Считаете non-null — ваша ответственность, NPE прилетит в рантайме.// В Swift третьего состояния между String и String? не бывает// ────────── 3. sealed + when == enum с ассоциированными значениями + switch ──────────sealed interface LoadResult { data class Ready(val orders: List<Order>) : LoadResult data class Failed(val reason: String) : LoadResult data object Loading : LoadResult}fun render(r: LoadResult) = when (r) { // уберёте ветку — ошибка сборки, is LoadResult.Ready -> showOrders(r.orders) // ровно как в Swift is LoadResult.Failed -> showError(r.reason) LoadResult.Loading -> showSpinner()}// ────────── 4. Корутины структурны, но гонки никто не проверяет ──────────class Counter { var value = 0 }suspend fun bump(counter: Counter) = coroutineScope { repeat(1000) { launch(Dispatchers.Default) { counter.value++ } }}// Компилируется без предупреждений и стабильно выдаёт не тысячу.// Swift 6 такой код не соберёт: Counter не Sendable, компилятор откажет
Так и видно, чем Kotlin отличается от Swift не по синтаксису, а по поведению.
Четвёртый пункт вообще выворачивает привычное представление. Swift 6 включил проверку гонок данных на этапе компиляции: протокол Sendable, изоляция акторов и регионная изоляция из SE-0414 позволяют компилятору доказать, что значение не пересекает границу конкурентности небезопасно. Kotlin даёт корутины, диспетчеры и структурные скоупы, а общее изменяемое состояние оставляет целиком на вас: Mutex, атомики, конфайнмент в один диспетчер. Kotlin обычно хвалят как более безопасный язык, и по работе с null это чистая правда, но человек из Swift 6 приходит сюда и обнаруживает, что страховки больше нет.
Compose и SwiftUI похожи ровно до первого профайлинга
Оба фреймворка про состояние и перерисовку, но обновляются они принципиально по-разному — об этом есть годная статья на medium с позиции Android-разработчика, залезшего в SwiftUI.
SwiftUI пересоздаёт значения-структуры представлений и сравнивает получившееся дерево с предыдущим. Compose работает иначе: composable-функции возвращают Unit и наверх не отдают ничего, через компиляторный плагин они пишут в структуру данных времени исполнения, а плагин расставляет точки позиционной мемоизации. Рантайм перезапускает не всё дерево, а конкретную функцию, у которой изменились входы.
Отсюда растёт понятие стабильности типов, которого в SwiftUI просто нет. Компилятор классифицирует параметры: у стабильного типа корректный equals, и при неизменности значения функцию можно пропустить. Долгое время это было источником народных страданий, потому что List<T> из стандартной библиотеки считается нестабильным — интерфейс, за которым может прятаться MutableList. Люди обкладывались @Immutable, тащили kotlinx.collections.immutable и всё равно ловили лишние перерисовки.
С Kotlin 2.0.20 по умолчанию включён strong skipping, и правила стали попроще: пропускаемыми становятся все перезапускаемые composable-функции независимо от стабильности параметров, нестабильные параметры сравниваются по ссылке через ===, а лямбды внутри composable запоминаются автоматически. Для того, кто переезжает, вывод такой: большая часть советов из статей 2022–2023 годов про @Stable и @Immutable сегодня протухла.
А вот ключи в списках никуда не делись. Без key у LazyColumn слоты переиспользуются по позиции, и после вставки элемента в начало вы перерисуете всё, что ниже — ровно та же логика, что id в ForEach у SwiftUI, только цена ошибки выше. Проверить можно счётчиками рекомпозиций в Layout Inspector и отчётами компилятора Compose.
Главный культурный шок
Если выбирать одно место, где переучиваться придётся больнее всего, я бы ткнул не в язык и не в UI, а в фон.
На iOS общих фоновых сервисов нет в принципе. Есть узкий список фоновых режимов (аудио, геолокация, VoIP, BLE, push-to-talk) плюс Live Activities как витрина «что-то происходит». Система ограничивает, зато правила простые.
На Android есть полноценные foreground-сервисы, и правил вокруг них накопилось на отдельную статью. С Android 14 сервис обязан объявлять тип, и система при создании проверяет разрешение: нет RECORD_AUDIO под сервисом типа microphone, ловите SecurityException. Android 15 добавил тайм-ауты: сервис типа dataSync работает суммарно шесть часов за сутки, после чего запуск нового даёт ForegroundServiceStartNotAllowedException, а shortService ограничен тремя минутами и не может сменить тип на ходу. В Android 16 фоновые задачи, запущенные из foreground-сервиса, подчиняются обычным квотам, включая те, что вы планируете через WorkManager.
Поверх системных правил лежит вендорский слой, разные производители по-своему агрессивно выгружают фоновые процессы, и приложение, идеально работающее на Pixel, может молча не доставлять уведомления на популярных в России моделях.
Что делать первые два месяца
Оговорюсь сразу: восемь недель — это срок, после которого вас можно сажать в команду на реальные задачи под присмотром. Чувство платформы набирается годами, и никакой план его не ускорит.
Первые две недели уходят на Kotlin, причём не на синтаксис. Синтаксис вы прочитаете за пару дней, он вам покажется знакомым, и вот это как раз опасно. Тратить время надо ровно на те места, где язык расходится со Swift: ссылочная семантика data-классов, платформенные типы из Java, отсутствие проверки гонок в корутинах. Плюс то, чему в Swift нет прямого аналога — делегаты свойств, scope-функции вроде let и apply, а sealed interface разбирается за полчаса, потому что это ваш enum с ассоциированными значениями под другим именем.
Третья неделя — про саму платформу. Жизненный цикл активити и фрагментов, ViewModel и то, как она переживает поворот экрана, рантайм-разрешения, навигация, ресурсы и квалификаторы конфигураций. Скучно, но без этого дальше никак: половина багов новичка растёт из непонимания, что система в любой момент может убить процесс и потом восстановить экран из сохранённого состояния.
Четвёртая и пятая недели — Compose. Состояние, remember, рекомпозиция, стабильность типов, ключи в списках, побочные эффекты через LaunchedEffect и DisposableEffect, темизация на Material 3. Здесь вы будете чаще всего обманываться сходством со SwiftUI, так что заранее откройте Layout Inspector и приучите себя смотреть на счётчики рекомпозиций, а не на ощущения.
Шестая неделя — архитектура: однонаправленный поток данных, MVVM или MVI, репозитории, внедрение зависимостей через Hilt или Koin. Идеи те же, что и на iOS, меняются только имена библиотек.
Седьмая — сеть и хранение. Ktor или Retrofit, Room или DataStore, сериализация через kotlinx.serialization. Восьмая — тесты и релизный цикл: юнит-тесты, тесты Compose, варианты сборки, подпись, публикация. Отдельно заложите время на выкладку не в один магазин, а сразу в Google Play и RuStore, потому что в России это давно норма.
Большая часть знаний переносится один в один, просто под другими именами:
|
SwiftUI и Swift |
Compose и Kotlin |
|
декларативный body |
@Composable-функция |
|
@State, @Binding |
remember { mutableStateOf() } и лямбда наверх |
|
@StateObject, ObservableObject |
ViewModel и StateFlow |
|
ForEach с id |
items(list, key = { it.id }) |
|
модификаторы через точку |
параметр modifier |
|
async/await |
корутины и suspend |
|
TaskGroup |
coroutineScope и launch |
|
Combine |
Flow, StateFlow, SharedFlow |
|
Task и отмена |
Job и кооперативная отмена |
Одинаковые по названию вещи ведут себя по-разному.
Что я про это думаю и где могу ошибаться
Если совсем коротко, у Android в России сложились сразу три вещи. Массовость: девять смартфонов из десяти здесь и семь из десяти в мире. Доставка, которая работает: Google Play, RuStore, свой APK, раздача через MDM, и если один канал отвалился, остальные на месте. И ширина: телефоны, планшеты, телевизоры, часы, кассы, киоски, головные устройства в машинах.
На iOS из 165 крупнейших банков в App Store доступны 37, в RuStore 98, второго канала нет и не предвидится. Первыми уходят не разработчики, а пользователи: человек просто хочет открыть банк и оплатить парковку, ему всё равно, чей это магазин. За пользователями подтягиваются продуктовые команды, потому что массовый сервис живёт там, где до людей можно дотянуться.
Ребят, ну как будто бы Android-разработчики сейчас в плюсе, нет? Не потому что платформа лучше сделана. Просто работы там больше и до пользователя она доезжает без чужого разрешения.
И мне кажется, интерес к Android тут не всплеск, который через полгода сдуется. Всё, что я перечислил это структура рынка, которая складывалась четыре года.
Хотя ошибаться я могу много где.
Короче, мне тут очень не хватает вас. Особенно тех, кто пишет под iOS. Как оно там вообще? Дистрибуция реально портит жизнь или я навыдумывал? Кто брал вторую платформу — что оказалось тяжелее, чем ждали? И если я где-то натянул, так и скажите.
ссылка на оригинал статьи https://habr.com/ru/articles/1085826/