Мобильный разработчик
80 задач. Условие и варианты ответа открыты всем; проверка, подсказка и разбор — в клубе.
Платформы и жизненный цикл приложения
- Счётчик обнуляется при повороте экрана: что произошло с Activity
- Камера перестала открываться после того, как пользователь зашёл в системные настройки
- Пользователь свернул приложение во время загрузки файла: что гарантирует система
- Экран закрыт, а корутина продолжает работать: чем плох GlobalScope во ViewModel
- Ошибка «setState() called after dispose» при быстром уходе с экрана
- Обновление UILabel из фоновой очереди: что не так с этим кодом
- Форма пустая после долгого пребывания приложения в фоне, хотя минуту назад всё сохранялось
- Кроссплатформа или два нативных приложения: как рассуждать при BLE и фоновой синхронизации
Сеть и хранение данных
- Сервер вернул 401 на запросе списка заказов: что делает клиент
- Список пользователей не отрисовывается, если сервер не прислал одно из полей
- Где хранить access- и refresh-токен на устройстве
- Двойные списания после автоматических повторов POST-запроса на оплату
- Лента должна открываться без интернета: как правильно устроить хранение
- Обновление из стора роняет приложение, а чистая установка работает
- После разрыва связи часть real-time сообщений теряется, часть приходит дважды
- В бесконечном скролле повторяются и пропадают записи при активной ленте
Архитектура и состояние экрана
- Загрузка данных экрана в MVVM: где ей место
- DTO сетевого слоя импортировали в use case: чем это плохо
- Зачем передавать репозиторий в конструктор ViewModel, а не создавать внутри
- Товар добавляется в корзину, но список на экране не меняется
- В поиске остаются результаты по недопечатанному запросу
- У ViewModel не вызывается deinit после закрытия экрана
- На экране одновременно спиннер и ошибка: как устроено состояние
- Тест про подписку падает по ночам в CI
Сборка, релиз и стабильность
- Почему в стор не выкладывают ту самую debug-сборку, которую тестировали
- В отчёте о крашах вместо имён методов однобуквенные классы и адреса
- Зачем раскатывать релиз сначала на 5% пользователей
- Пайплайн выкладывает сборку при упавших тестах: найдите причину в конфигурации
- Потерян ключ подписи опубликованного приложения
- Сорок минут UI-тестов и пятнадцать процентов случайных падений
- Через три часа после раскатки crash-free упал с 99,6 до 97,2 процента
- Продакт говорит «в пределах нормы»: как читать crash-free после релиза
Flutter и Dart: виджеты, рендер и асинхронность
- Экран профиля шлёт запрос к API на каждый введённый в поиск символ
- Каталог из 5000 товаров открывается три секунды и съедает память
- Поменял стартовое значение счётчика в initState, а после hot reload на экране старое
- Список под заголовком не рисуется, в консоли «Vertical viewport was given unbounded height»
- После удаления первой задачи из списка галочка «выполнено» перескакивает на соседнюю
- Разбор ответа на 8 МБ замораживает анимацию загрузки на полторы секунды, хотя код async
- Аналитика отправляет события не в том порядке, в котором их поставили в код
- Каждое изменение корзины перерисовывает весь экран каталога с сотней карточек
- Набранный текст в поле комментария стирается, когда приходит новое сообщение чата
- Галерея из 60 фото с камеры вылетает по памяти на Android с 3 ГБ ОЗУ
- Нативный модуль падает при передаче данных во Flutter из фонового потока
- Второй StreamBuilder на поток сообщений падает с «Stream has already been listened to»
React Native: списки, рендер и нативная часть
- История операций из 3000 строк открывается четыре секунды на среднем Android
- После ухода с экрана заказа статус доставки продолжает опрашиваться каждые 5 секунд
- Тень у карточки товара есть на iPhone, а на Android карточка плоская
- Поставили библиотеку для сканера QR, а на iOS приложение сразу падает с ошибкой про нативный модуль
- Обернули строку списка в React.memo, но при вводе в поиск перерисовываются все 200 строк
- Анимация появления карточек дёргается, пока приложение разбирает ответ сервера
- Таймер повторной отправки SMS застывает на 59 секундах
- Переход к сообщению из поиска падает с ошибкой scrollToIndex для далёкой строки
- Офлайн-каталог в AsyncStorage перестал загружаться на Android после роста до 15 МБ
- Лента объявлений на Android вылетает по памяти, хотя превью всего 100×100
- Ссылка на заказ открывает нужный экран, только если приложение уже было запущено
- После OTA-обновления у части пользователей падает экран оплаты
Kotlin Multiplatform: общий код для Android и iOS
- Модуль shared собирается под Android, но не под iOS из-за java.util.UUID
- Общему репозиторию авторизации нужен токен из Keychain и из Android Keystore
- Общий HttpClient на Ktor собирается, но на iOS не выполняет ни одного запроса
- iOS-команда боится, что после перехода на KMP придётся отказаться от SwiftUI
- Swift оборачивает вызов в do/catch, а приложение всё равно падает при ошибке сети
- Общий StateFlow корзины неудобно слушать из SwiftUI
- Общей базе SQLDelight на Android нужен Context, которого нет в commonMain
- На iOS после закрытия экрана поиска общий ViewModel продолжает слать запросы
- Статья советует замораживать объекты через freeze() перед передачей между потоками
- Два KMP-фреймворка в iOS-приложении не могут передать друг другу объект User
- Общая функция расчёта маршрута подвешивает интерфейс на iOS и Android
- Новый вариант sealed-класса оплаты тихо попал в default-ветку на iOS
Push-уведомления, Firebase и покупки в приложении
- Новые пользователи на Android 13 не получают ни одного push-уведомления
- После переустановки приложения пользователю перестали приходить уведомления о заказах
- Push через Firebase доходит до Android, а на iPhone тишина
- Поменял флаг в Remote Config, а тестовое приложение полдня видит старое значение
- Сообщение чата сохраняется в локальную базу, только когда приложение открыто
- Оплата молча не проходит у 3% пользователей, а в Crashlytics пусто
- Google Play возвращает деньги за подписку через три дня после покупки
- App Store отклонил обновление: нет способа восстановить купленный «Премиум навсегда»
- Премиум без оплаты: у пользователей модифицированной сборки открыты все функции
- Фоновая синхронизация по тихим push на iOS срабатывает через раз
- После выхода из аккаунта на общем планшете приходят уведомления прошлого пользователя
- Игрок заплатил за 500 кристаллов, но приложение упало, и кристаллы не начислились
