В Китае генеративные фичи вашего iOS-приложения могут отвечать иначе
Вызовы Writing Tools и фреймворка Foundation Models вы пишете один раз, а отвечать на них в разных регионах будут разные модели. The New Stack со ссылкой на Reuters пишет, что Apple собрала для Китая отдельную модель при участии Alibaba: ни ChatGPT, ни Gemini, ни Claude предоставлять там свои сервисы не могут, поэтому опереться можно только на то, что разработано или одобрено внутри страны. Рядом с новой моделью должен работать Qwen, возможно и технологии Baidu.
Какая модель отвечает за какую часть Apple Intelligence, ни Apple, ни партнёры не объяснили. Даты запуска тоже нет, Reuters ждёт сервис в ближайшие месяцы.
Так что генеративные фичи придётся тестировать на китайском аккаунте отдельно. Промпт, отлаженный на европейском регионе, там может ответить иначе.
#ios
Вызовы Writing Tools и фреймворка Foundation Models вы пишете один раз, а отвечать на них в разных регионах будут разные модели. The New Stack со ссылкой на Reuters пишет, что Apple собрала для Китая отдельную модель при участии Alibaba: ни ChatGPT, ни Gemini, ни Claude предоставлять там свои сервисы не могут, поэтому опереться можно только на то, что разработано или одобрено внутри страны. Рядом с новой моделью должен работать Qwen, возможно и технологии Baidu.
Какая модель отвечает за какую часть Apple Intelligence, ни Apple, ни партнёры не объяснили. Даты запуска тоже нет, Reuters ждёт сервис в ближайшие месяцы.
Так что генеративные фичи придётся тестировать на китайском аккаунте отдельно. Промпт, отлаженный на европейском регионе, там может ответить иначе.
#ios
Код на C во Flutter дёргается из Dart напрямую, без обвязки под каждую платформу
Готовый код на C в приложении (кодек, крипта, обработка картинок) обычно заворачивают в platform channel, и обвязку пишут дважды: под Android и под iOS. Dart FFI этот слой убирает, Dart вызывает C-функцию сам.
Цена: сигнатуры руками. На каждую функцию объявляете два typedef, один в типах FFI (Int32 Function(Int32, Int32)), второй в дартовых (int Function(int, int)). А функция в библиотеке должна быть с C-совместимым ABI, иначе Dart не найдёт символ.
Загрузка зависит от платформы: на Android библиотека открывается по имени файла, DynamicLibrary.open('libnative_math.so'), в остальных случаях символ ищут в самом процессе приложения, DynamicLibrary.process().
Туториал на dev.to собирает минимальный проект и говорит, где FFI не нужен: под платформенные API Android и iOS ближе platform channels.
#flutter
Готовый код на C в приложении (кодек, крипта, обработка картинок) обычно заворачивают в platform channel, и обвязку пишут дважды: под Android и под iOS. Dart FFI этот слой убирает, Dart вызывает C-функцию сам.
Цена: сигнатуры руками. На каждую функцию объявляете два typedef, один в типах FFI (Int32 Function(Int32, Int32)), второй в дартовых (int Function(int, int)). А функция в библиотеке должна быть с C-совместимым ABI, иначе Dart не найдёт символ.
Загрузка зависит от платформы: на Android библиотека открывается по имени файла, DynamicLibrary.open('libnative_math.so'), в остальных случаях символ ищут в самом процессе приложения, DynamicLibrary.process().
Туториал на dev.to собирает минимальный проект и говорит, где FFI не нужен: под платформенные API Android и iOS ближе platform channels.
#flutter
👍2❤1
Релиз Flutter-приложения в сторы можно свести к одному пушу в ветку
Билд для тестировщиков к вечеру пятницы обычно выглядит так: архив в Xcode, ошибка подписи, повторный архив, загрузка в TestFlight. Потом то же для Android: подписать APK, залить в Firebase App Distribution, добавить тестировщиков и заметки.
В руководстве freeCodeCamp это перекладывают на GitHub Actions и Fastlane: пуш в ветку dev собирает APK и IPA на серверах GitHub и раздаёт их в Firebase App Distribution и TestFlight, пуш в prod уходит в Google Play и App Store Connect.
Дольше всего настраивается подпись iOS: fastlane match держит сертификаты и профили в отдельном приватном репозитории, а сборка расшифровывает их паролем из секретов GitHub. Ещё нужны ключ App Store Connect API и сервисный аккаунт Google Play.
Начинать стоит с тестовых сборок: стор-релизы подключаются потом той же схемой.
#flutter
Билд для тестировщиков к вечеру пятницы обычно выглядит так: архив в Xcode, ошибка подписи, повторный архив, загрузка в TestFlight. Потом то же для Android: подписать APK, залить в Firebase App Distribution, добавить тестировщиков и заметки.
В руководстве freeCodeCamp это перекладывают на GitHub Actions и Fastlane: пуш в ветку dev собирает APK и IPA на серверах GitHub и раздаёт их в Firebase App Distribution и TestFlight, пуш в prod уходит в Google Play и App Store Connect.
Дольше всего настраивается подпись iOS: fastlane match держит сертификаты и профили в отдельном приватном репозитории, а сборка расшифровывает их паролем из секретов GitHub. Ещё нужны ключ App Store Connect API и сервисный аккаунт Google Play.
Начинать стоит с тестовых сборок: стор-релизы подключаются потом той же схемой.
#flutter
❤1
Автоматизация в приложении не должна ждать сеть, и на Android её можно собрать целиком на устройстве
Вы вешаете смену профиля звука на правило из Firebase, и в метро приложение молчит: пора срабатывать, а ответа сервера нет. То же в самолёте и на слабой связи.
Автор Muffle, приложения для беззвучного режима по времени и месту, вынес состояние на устройство: Room как единственный источник правды, WorkManager для периодических проверок, Geofencing API для геозон, AlarmManager для времени, а профили переключает ForegroundService через AudioManager.
Учтите: ForegroundService нужно объявить типом в манифесте и обосновать в Google Play Console, иначе релиз рискует не пройти ревью. И геозоны с будильниками после перезагрузки регистрируются заново, сверяться с сервером не с чем. Как автор делает переходы состояний атомарными, чтобы телефон не остался в беззвучном режиме навсегда.
#android
Вы вешаете смену профиля звука на правило из Firebase, и в метро приложение молчит: пора срабатывать, а ответа сервера нет. То же в самолёте и на слабой связи.
Автор Muffle, приложения для беззвучного режима по времени и месту, вынес состояние на устройство: Room как единственный источник правды, WorkManager для периодических проверок, Geofencing API для геозон, AlarmManager для времени, а профили переключает ForegroundService через AudioManager.
Учтите: ForegroundService нужно объявить типом в манифесте и обосновать в Google Play Console, иначе релиз рискует не пройти ревью. И геозоны с будильниками после перезагрузки регистрируются заново, сверяться с сервером не с чем. Как автор делает переходы состояний атомарными, чтобы телефон не остался в беззвучном режиме навсегда.
#android
❤🔥1
Одна булева проверка на root отключается хуком, но защиту можно собрать иначе
Альтернатива: не сводить решение к одному флагу. Библиотека DeviceTrust на Kotlin и C++ собирает низкоуровневые сигналы (root, эмулятор, кастомный ROM, разблокированный загрузчик, Frida и Xposed, модифицированный APK) и превращает их в оценку риска.
Сам по себе ни один сигнал ничего не доказывает: телефон рутуют из интереса, эмулятор гоняют для разработки. Смысл появляется, когда несколько признаков сходятся вместе с подозрительным поведением, поэтому оценка нужна как часть антифрод-системы, а не как if на клиенте.
Библиотека в версии 0.1.2, для прода рано. Подход забрать можно уже сейчас.
#android #kotlin
if (isRooted()) blockUser() работает ровно до того момента, когда атакующий находит этот метод. Frida перехватывает вызов и подменяет возвращаемое значение: true становится false, и проверки больше нет.Альтернатива: не сводить решение к одному флагу. Библиотека DeviceTrust на Kotlin и C++ собирает низкоуровневые сигналы (root, эмулятор, кастомный ROM, разблокированный загрузчик, Frida и Xposed, модифицированный APK) и превращает их в оценку риска.
Сам по себе ни один сигнал ничего не доказывает: телефон рутуют из интереса, эмулятор гоняют для разработки. Смысл появляется, когда несколько признаков сходятся вместе с подозрительным поведением, поэтому оценка нужна как часть антифрод-системы, а не как if на клиенте.
Библиотека в версии 0.1.2, для прода рано. Подход забрать можно уже сейчас.
#android #kotlin
Уведомление вашего приложения не удержать наверху шторки, но обход есть
Вы шлёте код подтверждения через NotificationManager.notify(), канал с высокой важностью, а пользователь пишет, что ничего не приходило: промо из игры вытеснило код вниз.
Шторкой владеет системный менеджер уведомлений, и это отсортированный по времени список: новое сверху. Важность в Android выражена через прерывание, а не через позицию: звук, heads-up, исключения в «Не беспокоить». Поля «держать сверху, пока не закроют» у Notification нет, и приоритетный канал его не заменяет: приоритет означает конкурировать с другими приоритетными.
Обход один: NotificationListenerService, система дёргает его на каждое появление и снятие уведомления, включая чужие. Тот же хук, что у экранного времени и авто-ответов; в разборе на dev.to это ~80 строк. Цена — разрешение, которое пользователь выдаёт руками в настройках.
#android
Вы шлёте код подтверждения через NotificationManager.notify(), канал с высокой важностью, а пользователь пишет, что ничего не приходило: промо из игры вытеснило код вниз.
Шторкой владеет системный менеджер уведомлений, и это отсортированный по времени список: новое сверху. Важность в Android выражена через прерывание, а не через позицию: звук, heads-up, исключения в «Не беспокоить». Поля «держать сверху, пока не закроют» у Notification нет, и приоритетный канал его не заменяет: приоритет означает конкурировать с другими приоритетными.
Обход один: NotificationListenerService, система дёргает его на каждое появление и снятие уведомления, включая чужие. Тот же хук, что у экранного времени и авто-ответов; в разборе на dev.to это ~80 строк. Цена — разрешение, которое пользователь выдаёт руками в настройках.
#android
Очередь из приложения не доедет до iOS-виджета, но для моста хватит нескольких ID
Прогресс изменился, а виджет должен показать следующее слово. Передать ему объект состояния напрямую нельзя: WidgetKit запускает расширение отдельным процессом.
В Slovo приложение сохраняет в хранилище App Group, общем для приложения и расширения, ID текущего слова и до пяти ID для повторения. Затем WidgetKit пересобирает расписание: по записи на каждый час следующих суток, сначала слово дня, потом слова для повторения. База и планирование остаются в приложении.
Сначала определите минимальный снимок состояния для расширения и обновляйте расписание после записи. Так логика не разъедется между двумя процессами. В разборе на HackerNoon есть код обмена и сборки расписания на 24 часа.
Прогресс изменился, а виджет должен показать следующее слово. Передать ему объект состояния напрямую нельзя: WidgetKit запускает расширение отдельным процессом.
В Slovo приложение сохраняет в хранилище App Group, общем для приложения и расширения, ID текущего слова и до пяти ID для повторения. Затем WidgetKit пересобирает расписание: по записи на каждый час следующих суток, сначала слово дня, потом слова для повторения. База и планирование остаются в приложении.
Сначала определите минимальный снимок состояния для расширения и обновляйте расписание после записи. Так логика не разъедется между двумя процессами. В разборе на HackerNoon есть код обмена и сборки расписания на 24 часа.
😐2
Google вводит лимиты памяти для Android-приложений, срок до февраля 2027
Причина внешняя: бум ИИ-дата-центров выел рынок чипов памяти, и бюджетные телефоны получают меньше оперативки. Google формулирует это как значительные ограничения поставок железа, меняющие доступность памяти на устройствах.
Практическая часть для разработчика: появляются новые пороги по использованию памяти и по битмапам, уложиться в них нужно до февраля 2027 года. Заодно Google обещает инструменты, которые подсветят приложения, вылезающие за лимиты, чтобы поймать тормоза и падения заранее.
Если у вас тяжёлая работа с изображениями, смотреть на битмапы стоит начинать сейчас, а не за месяц до срока. Заметка со ссылкой на TechCrunch.
#android
Причина внешняя: бум ИИ-дата-центров выел рынок чипов памяти, и бюджетные телефоны получают меньше оперативки. Google формулирует это как значительные ограничения поставок железа, меняющие доступность памяти на устройствах.
Практическая часть для разработчика: появляются новые пороги по использованию памяти и по битмапам, уложиться в них нужно до февраля 2027 года. Заодно Google обещает инструменты, которые подсветят приложения, вылезающие за лимиты, чтобы поймать тормоза и падения заранее.
Если у вас тяжёлая работа с изображениями, смотреть на битмапы стоит начинать сейчас, а не за месяц до срока. Заметка со ссылкой на TechCrunch.
#android
developers.slashdot.org
AI's Memory Crunch Is Coming For Android Apps
Google is imposing new memory-use limits on Android apps as the AI data center boom contributes to a broader memory chip shortage that could leave lower-cost phones with less RAM. Developers will have until February 2027 to meet new thresholds for memory…
Суд велел Google убрать лишние шаги из установки сторонних Android-сторов
Если вы раздаёте приложение мимо Google Play, пользователю надо пройти цепочку экранов и предупреждений. Часть этих шагов судья Джеймс Донато назвал «антиконкурентным трением» и приказал убрать.
Epic показала в суде установку чужого стора, а её юрист ввёл в поиске Play запрос «store for apps»: сторонних магазинов приложений в выдаче нет, зато есть офлайновые. «Почему всплыл Walmart?» — спросил судья.
Раньше тот же суд признал монополию Google на распространение Android-приложений незаконной и обязал на несколько лет пустить конкурирующие сторы внутрь Play с доступом ко всему каталогу. Для мобильного разработчика это второй канал дистрибуции, и на нём должно отсеиваться меньше пользователей.
Дело идёт в США. Если раздаёте приложение вне Play, следите, как Google перепишет экраны установки.
#android #новости
Если вы раздаёте приложение мимо Google Play, пользователю надо пройти цепочку экранов и предупреждений. Часть этих шагов судья Джеймс Донато назвал «антиконкурентным трением» и приказал убрать.
Epic показала в суде установку чужого стора, а её юрист ввёл в поиске Play запрос «store for apps»: сторонних магазинов приложений в выдаче нет, зато есть офлайновые. «Почему всплыл Walmart?» — спросил судья.
Раньше тот же суд признал монополию Google на распространение Android-приложений незаконной и обязал на несколько лет пустить конкурирующие сторы внутрь Play с доступом ко всему каталогу. Для мобильного разработчика это второй канал дистрибуции, и на нём должно отсеиваться меньше пользователей.
Дело идёт в США. Если раздаёте приложение вне Play, следите, как Google перепишет экраны установки.
#android #новости
👍9❤1
Arm обещает ускорить мобильную графику без лишнего нагрева
Mali G2-Ultra NX — новый мобильный GPU, рассчитанный на нейронные вычисления. Arm утверждает, что обработка ИИ прямо на устройстве повысит графическую производительность и позволит активнее использовать трассировку лучей при меньшем расходе энергии и тепловыделении.
Для разработчиков это пока ориентир, а не готовый пункт плана релиза: в Arm не подтвердили, какие устройства получат чип. GPU уже связывают с MegaLights в Unreal Engine; его возможности должны использовать Arena Breakout Infinite, Where Winds Meet и Infinity Nikki.
В материале GamesIndustry.biz объясняют, почему Arm считает свой подход более открытым, чем DLSS 5, и как компания хочет приблизить мобильную графику к настольной.
Mali G2-Ultra NX — новый мобильный GPU, рассчитанный на нейронные вычисления. Arm утверждает, что обработка ИИ прямо на устройстве повысит графическую производительность и позволит активнее использовать трассировку лучей при меньшем расходе энергии и тепловыделении.
Для разработчиков это пока ориентир, а не готовый пункт плана релиза: в Arm не подтвердили, какие устройства получат чип. GPU уже связывают с MegaLights в Unreal Engine; его возможности должны использовать Arena Breakout Infinite, Where Winds Meet и Infinity Nikki.
В материале GamesIndustry.biz объясняют, почему Arm считает свой подход более открытым, чем DLSS 5, и как компания хочет приблизить мобильную графику к настольной.
Аська. Скайп. Биткоин, который все игнорировали. «Превед медвед» и Ждун в ленте. Всё это — в одной анкете. Пройди и узнай, сколько информации можно было бы на тебя записать.
Все дела подождут, потому что сегодня ваш день!
Поздравляем с Днем программиста и желаем меньше багов и больше фич, меньше созвонов и больше фокуса, меньше тасок с пометкой «срочно» и больше времени на отдых.
Забирайте подарок из нашей IT-коробки. Мы уверены, этот презент точно пригодится вам в работе: https://tprg.ru/4kC6
Поздравляем с Днем программиста и желаем меньше багов и больше фич, меньше созвонов и больше фокуса, меньше тасок с пометкой «срочно» и больше времени на отдых.
Забирайте подарок из нашей IT-коробки. Мы уверены, этот презент точно пригодится вам в работе: https://tprg.ru/4kC6
❤🔥2👍2🔥2
Как сохранить экран Android после завершения процесса
Когда системе не хватает памяти, Android может завершить процесс приложения. При возвращении выбранная карточка или поля формы пропадут, если состояние осталось только во ViewModel.
SavedStateHandle хранит небольшое состояние интерфейса как пары ключей и значений. В примере на Kotlin и Compose идентификатор места записывается из ViewModel, а
Так стоит сохранять идентификаторы, ввод формы и состояние навигации. Для больших объектов и долгого хранения нужны Room или DataStore. SavedStateHandle переживает системное завершение процесса и смену конфигурации, но не явное закрытие приложения. Код и рекомендации есть в разборе Atomic Object.
Когда системе не хватает памяти, Android может завершить процесс приложения. При возвращении выбранная карточка или поля формы пропадут, если состояние осталось только во ViewModel.
SavedStateHandle хранит небольшое состояние интерфейса как пары ключей и значений. В примере на Kotlin и Compose идентификатор места записывается из ViewModel, а
getStateFlow() возвращает поток состояния, который передаёт новое значение интерфейсу. При уходе с экрана запись очищается через null.Так стоит сохранять идентификаторы, ввод формы и состояние навигации. Для больших объектов и долгого хранения нужны Room или DataStore. SavedStateHandle переживает системное завершение процесса и смену конфигурации, но не явное закрытие приложения. Код и рекомендации есть в разборе Atomic Object.
Как обновлять токен без гонок в Swift
Если срок действия токена истёк у нескольких запросов, каждый из них может запустить обновление. В схеме из статьи
Перед сетевым вызовом
В разборе потока на Swift Concurrency показаны реализации обоих объектов. Пример упрощён: токен хранится в свойстве только для демонстрации, а в приложении автор рекомендует Keychain.
Если срок действия токена истёк у нескольких запросов, каждый из них может запустить обновление. В схеме из статьи
AuthManager сделан актором: он последовательно обращается к своему состоянию и хранит текущую Task. Первый вызов создаёт задачу обновления, остальные ждут её результат. После завершения defer очищает ссылку на задачу. Так приложение отправляет один запрос на новый токен вместо нескольких.Перед сетевым вызовом
Networking просит у менеджера действующий токен. Если запрос завершается ошибкой из-за токена, клиент обновляет его и повторяет исходный запрос один раз. Повторная ошибка завершает операцию, поэтому цикл не становится бесконечным.В разборе потока на Swift Concurrency показаны реализации обоих объектов. Пример упрощён: токен хранится в свойстве только для демонстрации, а в приложении автор рекомендует Keychain.
👍2
Как Android фиксирует ANR и почему стек вызовов может указать не туда
В Android 12 у ANR нет одного общего таймера. Фреймворк задаёт срок каждой операции: BroadcastReceiver должен завершить
Стек вызовов может показать последнюю задачу в главном потоке, а не основную причину. В примере BroadcastReceiver занимает 4,8 секунды, затем Activity ещё 0,3 секунды, однако виновником выглядит Activity. Поэтому ищите повторяющуюся медленную работу в отчётах, а не чините каждый стек изолированно.
ANR из-за таймаута ввода попадают в Android Vitals и влияют на видимость приложения в Google Play. Разбор Embrace показывает цепочку срабатывания и сбора данных. Материал касается Android 12; в других версиях реализация может отличаться.
В Android 12 у ANR нет одного общего таймера. Фреймворк задаёт срок каждой операции: BroadcastReceiver должен завершить
onReceive за 10 секунд, ContentProvider ответить на запрос типа данных за одну. Если компонент успел, отложенный вызов отменяют; иначе система запускает обработку ANR.Стек вызовов может показать последнюю задачу в главном потоке, а не основную причину. В примере BroadcastReceiver занимает 4,8 секунды, затем Activity ещё 0,3 секунды, однако виновником выглядит Activity. Поэтому ищите повторяющуюся медленную работу в отчётах, а не чините каждый стек изолированно.
ANR из-за таймаута ввода попадают в Android Vitals и влияют на видимость приложения в Google Play. Разбор Embrace показывает цепочку срабатывания и сбора данных. Материал касается Android 12; в других версиях реализация может отличаться.
Как собрать Flutter-приложение, которое работает без сети
В архитектуре с приоритетом локальных данных экран читает и меняет базу на устройстве. Создание задачи не ждёт сервера: изменения уходят к нему после возвращения связи. Приложение продолжает работу, но разработчику нужно разрешать конфликты правок и сбои синхронизации.
Автор показывает Todo-приложение: Riverpod управляет состоянием и зависимостями, Drift хранит данные на устройстве, а PowerSync отслеживает изменения и синхронизирует их с Supabase. Также разобраны очередность операций, повторы после ошибок и пакетная отправка изменений.
В статье Динко Маринаца есть схема слоёв и ключевые фрагменты реализации. Для Flutter-проекта это отправная точка: интерфейс работает с локальной базой, а сетевой запрос не блокирует действие пользователя.
В архитектуре с приоритетом локальных данных экран читает и меняет базу на устройстве. Создание задачи не ждёт сервера: изменения уходят к нему после возвращения связи. Приложение продолжает работу, но разработчику нужно разрешать конфликты правок и сбои синхронизации.
Автор показывает Todo-приложение: Riverpod управляет состоянием и зависимостями, Drift хранит данные на устройстве, а PowerSync отслеживает изменения и синхронизирует их с Supabase. Также разобраны очередность операций, повторы после ошибок и пакетная отправка изменений.
В статье Динко Маринаца есть схема слоёв и ключевые фрагменты реализации. Для Flutter-проекта это отправная точка: интерфейс работает с локальной базой, а сетевой запрос не блокирует действие пользователя.
Как не сортировать данные заново при пересчёте SwiftUI-представления
Вычисляемое свойство в Swift пересчитывается при каждом обращении. Если
Автор разбирает три варианта: сортировать данные при загрузке и передавать представлению готовый массив, выполнить сортировку в
Материал Swift by Sundell написан для Swift 5.4 и перенесён в архив, поэтому примеры API стоит сверять с текущим SwiftUI. Проверьте вычисляемые свойства, которые сортируют или преобразуют коллекции при пересчёте
Вычисляемое свойство в Swift пересчитывается при каждом обращении. Если
body читает sortedItems, то ввод каждого символа в TextField меняет локальное состояние, заново вычисляет body и снова сортирует словарь напоминаний. На большой коллекции эта работа может стать заметной.Автор разбирает три варианта: сортировать данные при загрузке и передавать представлению готовый массив, выполнить сортировку в
init или вынести её в модель представления с ObservableObject. Инициализатор сокращает повторы, но родительский body может создать новый экземпляр представления и снова запустить сортировку.Материал Swift by Sundell написан для Swift 5.4 и перенесён в архив, поэтому примеры API стоит сверять с текущим SwiftUI. Проверьте вычисляемые свойства, которые сортируют или преобразуют коллекции при пересчёте
body.👏1
try/catch или Result: как обрабатывать ошибки во Flutter
В Dart сигнатура Future<Location> не показывает, что функция может бросить исключение. Без try/catch сетевой сбой или ошибка разбора JSON могут остаться необработанными.
В материале Code with Andrea показана альтернатива из Dart 3: тип Result возвращает либо Success со значением, либо Failure с исключением. В switch код отдельно разбирает Success и Failure; если убрать один вариант, компилятор сообщит об ошибке.
Цена зависит от структуры кода. Один try/catch перехватывает исключение из всей цепочки асинхронных вызовов. Result делает ошибку частью типа возврата, но каждый промежуточный результат приходится извлекать перед следующим вызовом. Сравнение поможет выбрать подход для Flutter-приложения.
В Dart сигнатура Future<Location> не показывает, что функция может бросить исключение. Без try/catch сетевой сбой или ошибка разбора JSON могут остаться необработанными.
В материале Code with Andrea показана альтернатива из Dart 3: тип Result возвращает либо Success со значением, либо Failure с исключением. В switch код отдельно разбирает Success и Failure; если убрать один вариант, компилятор сообщит об ошибке.
Цена зависит от структуры кода. Один try/catch перехватывает исключение из всей цепочки асинхронных вызовов. Result делает ошибку частью типа возврата, но каждый промежуточный результат приходится извлекать перед следующим вызовом. Сравнение поможет выбрать подход для Flutter-приложения.
❤1
Как подготовить Android-приложение к лимитам памяти в Android 17
В Android 17 появились лимиты памяти для каждого приложения, сначала на Pixel. Их начнут применять другие производители на устройствах с 4–16+ ГБ ОЗУ. После превышения бюджета система переносит страницы приложения в сжатую оперативную память. Сжатие нагружает процессор, поэтому интерфейс может дёргаться. Если расход продолжит расти, процесс завершат.
До релиза проверьте приложение командами Memory Limiter в adb. В работе отслеживайте расход и память изображений через Android vitals. Crashlytics 20.1.0 покажет завершения по лимиту и нехватке памяти, а ProfilingManager из Android 15 соберёт дампы памяти. В статье Android Developers' Blog собраны метрики, способы диагностики и рекомендации по оптимизации.
В Android 17 появились лимиты памяти для каждого приложения, сначала на Pixel. Их начнут применять другие производители на устройствах с 4–16+ ГБ ОЗУ. После превышения бюджета система переносит страницы приложения в сжатую оперативную память. Сжатие нагружает процессор, поэтому интерфейс может дёргаться. Если расход продолжит расти, процесс завершат.
До релиза проверьте приложение командами Memory Limiter в adb. В работе отслеживайте расход и память изображений через Android vitals. Crashlytics 20.1.0 покажет завершения по лимиту и нехватке памяти, а ProfilingManager из Android 15 соберёт дампы памяти. В статье Android Developers' Blog собраны метрики, способы диагностики и рекомендации по оптимизации.
Task и Task.detached в Swift: как выбрать задачу для iOS-кода
Обычная
В статье о задачах Swift разобраны оба варианта с кодом. Практическое правило: начинайте с
Обычная
Task {} пригодится, когда нужно вызвать async-функцию из синхронного viewDidLoad. Такая задача не становится дочерней: вызвавший её метод может завершиться раньше. При этом она наследует текущий актор, локальные значения задачи и приоритет. Поэтому внутри @MainActor код задачи остаётся в изоляции текущего актора, а ожидание через await не блокирует актор.Task.detached не наследует ни актор, ни локальные значения задачи. Для доступа к состоянию актора понадобится await. При этом detached-задача не определяет, где исполняется вызываемая async-функция: это задаёт изоляция самой функции.В статье о задачах Swift разобраны оба варианта с кодом. Практическое правило: начинайте с
Task, а Task.detached оставляйте для редкой работы, которую нужно отделить от актора и структурированной конкурентности.Как защитить доступность iOS-приложения от регрессий
Разметить элементы для VoiceOver недостаточно: после редизайна доступный сценарий может сломаться. В 2ГИС первая версия адаптации со временем именно так и потеряла работоспособность.
Во второй итерации разработчик начал со snapshot-тестов. Они сохраняют текстовый слепок экрана: набор элементов и фразы, которые услышит незрячий пользователь. Если слепок меняется, тест падает до слияния кода. Автор выбрал этот путь вместо UI-тестов, которые выполняются десятки секунд, а причину расхождения здесь видно в тексте.
В статье 2ГИС на Хабре есть рабочий проект и нюансы адаптации: действие Escape, динамический расчёт доступности и укрупнение элементов. Подход пригодится командам с частыми изменениями интерфейса, где ручная регрессия VoiceOver не успевает за разработкой.
Разметить элементы для VoiceOver недостаточно: после редизайна доступный сценарий может сломаться. В 2ГИС первая версия адаптации со временем именно так и потеряла работоспособность.
Во второй итерации разработчик начал со snapshot-тестов. Они сохраняют текстовый слепок экрана: набор элементов и фразы, которые услышит незрячий пользователь. Если слепок меняется, тест падает до слияния кода. Автор выбрал этот путь вместо UI-тестов, которые выполняются десятки секунд, а причину расхождения здесь видно в тексте.
В статье 2ГИС на Хабре есть рабочий проект и нюансы адаптации: действие Escape, динамический расчёт доступности и укрупнение элементов. Подход пригодится командам с частыми изменениями интерфейса, где ручная регрессия VoiceOver не успевает за разработкой.