Forwarded from Flutter & Dart | Мобильный трудоголик
С августа 2026 года установка APK-файлов от неизвестных разработчиков на Android станет сложнее. Google вводит продвинутый процесс, который должен защитить пользователей от мошенников, но заодно превращает установку любого приложения не из Google Play в квест.
Это касается не только нативных разработчиков, но и разработчиков на Flutter, которые собирают приложения под Android и которые распространяют свои приложения в обход Google Play (например через сайты, соц. сети или телеграм). Это означает, что привычный способ «включил неизвестные источники -> установил» больше не сработает. Вместо этого - сутки ожидания, биометрия и подтверждение, что вас никто не принуждает.
Что изменится:
Раньше достаточно было включить разрешение на установку из неизвестных источников и можно было ставить любой APK. Теперь нужно будет пройти целую процедуру:
Только после этого можно будет устанавливать приложения от неизвестных разработчиков. И то - каждые семь дней процедуру, возможно, придется повторять.
Почему ввели данный процесс:
Google объясняет это борьбой с мошенниками. По статистике Global Anti-Scam Alliance, 57% взрослых сталкивались с мошенничеством за последний год, а ущерб составил 442 миллиарда долларов. Мошенники часто давят на жертв по телефону, заставляя прямо сейчас отключить защиту и установить вредоносное приложение. Принудительная пауза в сутки должна сломать эту схему.
Для тех, кто просто хочет установить приложение от независимого разработчика, это кажется излишним и выглядит как наказание.
Android теряет одну из главных своих особенностей - свободу установки любого приложения без ограничений. Теперь это будет возможно только после процедуры с суточным ожиданием. Google говорит о безопасности и это действительно важная тема. Для нативных разработчиков и Flutter-разработчиков, которые тестируют сборки на реальных устройствах, раздают бета-версии клиентам через телеграм или просто устанавливают собственные APK в процессе разработки, это ощущается как шаг назад. В погоне за защитой от мошенников страдают в том числе разработчики, которым нужна возможность быстро ставить приложения не из магазина.
Please open Telegram to view this post
VIEW IN TELEGRAM
🫡13👍6🤯3❤1🔥1👀1🗿1
В современных приложениях пользователь привык к интерактивности: перетащил фотографию в альбом, переместил задачу между колонками, кинул файл в папку. В 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
Forwarded from Кот Денисова
Карьера разработчика - это постоянное движение вперед. Часто приходит момент, когда чувствуешь, что готов к более сложным задачам и большей ответственности.
Как определить, что это действительно так и пора расти дальше? Есть несколько четких признаков, которые помогут это понять:
Что делать, если вы обнаружили эти признаки.
Не бегите к руководителю с требованием повышения. Подойдите с предложением.
Рост - это не только новая должность. Это часто и новые технологии.
Возможно, вы чувствуете, что уперлись в потолок текущего стека и хотите освоить новый. Главный страх здесь - потеря дохода во время перехода. Стратегия безопасной смены стека:
hh.ru, LinkedIn и других сервисах по поиску работы. Добавьте пункт об опыте работы с новым стеком, даже если это пет-проект. Это честно и убедительно.Не забывайте о фундаменте, который не устаревает.
Ваша долгосрочная ценность не в знании конкретного фреймворка, а в глубоком понимании принципов. Это то, что отличает исполнителя от архитектора решений:
Фреймворки меняются, а законы хорошего дизайна остаются. Инвестиции в эти знания гарантируют ваш рост и востребованность на протяжении всей карьеры.
Ваш профессиональный путь в ваших руках. Начните с честной самооценки, перейдите к конструктивному диалогу, дополните рост в должности развитием экспертизы в новых и фундаментальных областях. Именно так строятся карьеры, которыми гордятся. Карьера в ИТ - это ваш личный продукт, и вы его главный менеджер.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍8👏2🗿2🙏1
Apple объявила о крупнейшем обновлении аналитики в App Store Connect с момента запуска. Теперь разработчикам доступно более 100 новых метрик, которые позволяют детально анализировать монетизацию, подписки и поведение пользователей. Старые отчеты постепенно уходят в прошлое - стандартные панели перестанут работать уже в середине этого года.
Что нового:
Главное - данные стали детальнее и удобнее для анализа. Раньше разработчики полагались на сторонние сервисы, которые строили оценки на основе выборочных данных. Теперь Apple дает доступ к собственной статистике без посредников.
Ключевые изменения:
Для тех, кто монетизирует приложения через подписки или внутриигровые покупки, обновление App Store Connect - значимый шаг. Раньше полноценная аналитика была доступна только через платные сторонние сервисы. Теперь Apple дает аналогичные инструменты бесплатно и данные основаны на реальных цифрах, а не на оценках. Это делает анализ эффективности приложения более точным и прозрачным. Остается только разобраться в новых метриках, понять, как их правильно интерпретировать и грамотно использовать.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍8❤3🙏1🤝1
С 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
@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
Forwarded from Flutter & Dart | Мобильный трудоголик
Команда Flutter опубликовала размышления о том, как искусственный интеллект влияет на развитие экосистемы. Это не дорожная карта, а скорее честный взгляд на текущую ситуацию. Потому что в 2026 году невозможно делать инструменты для разработки, не обращая внимания на ИИ.
Цифры, которые объясняют все:
Согласно опросам, 84% разработчиков в целом используют ИИ-инструменты в своей работе. Среди Flutter-разработчиков этот показатель чуть ниже - 79%, но все равно впечатляет. Однако есть проблема: 46% не доверяют точности ИИ при решении критических задач. Это тратит лишнее время на проверку сгенерированного кода.
Главные принципы:
Команда декларирует несколько ключевых правил, которым следует при развитии ИИ-направления:
Команда Flutter не пытается предсказать будущее ИИ, а экспериментирует на виду, честно говоря о своих намерениях. ИИ не станет обязательной частью экосистемы, но для тех, кто хочет его использовать, инструменты будут. И при этом никто не заставляет отказываться от традиционной разработки - это тоже полностью валидный путь. Главное - чтобы у разработчика был выбор.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥5❤2🙏1👀1🫡1
Всем привет! Наткнулся на интересную статью, в которой автор рассказывает про поиск причины падения приложения при сворачивании на одном из экранов. В краш-логе не было ни одной строчки кода приложения, только системные фреймы QuartzCore, UIKit и Core Animation. Address Sanitizer ничего не показывал, а воспроизвести проблему без долгих танцев с бубном не получалось.
Что предложил автор:
Вместо того чтобы гадать, он взялся за LLDB. Сначала посмотрел bt (backtrace) - стек вызовов в момент падения. Анализируя его снизу вверх, стало ясно: приложение сворачивалось, система делала снимок экрана, обходила иерархию вьюх и у одной из них запрашивала superview. Именно там и происходил краш.
Дальше - frame select 0 и register read. В регистре x15 отладчик показал символ CrashExample.PlayerView - намек, что проблема связана с плеерным view. А падающая инструкция (ldr x8, [x8,
#0x8]) указала, что регистр x8 был нулевым. Чтение по адресу 0x8 и вызывало EXC_BAD_ACCESS.К чему это привело:
В коде нашли метод, который удалял playerLayer из суперслоя, но саму PlayerView из иерархии не убирал. Вьюха остается в subviews, но ее слой уже мертв. Когда система доходит до нее при обходе, случается краш.
Исправление оказалось простым: вместо ручного удаления слоя вызывать playerView.removeFromSuperview().
Статья - хороший пример того, что делать, когда краш-лог не содержит полезных фреймов, а санитайзеры молчат. LLDB не панацея, но умение читать backtrace, смотреть регистры и дизассемблер может превратить часы гадания в целенаправленный поиск.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18 12🙏3❤2👀1🤝1
Задумывались ли вы, как разные приложения на вашем iPhone так легко обмениваются данными? Вы копируете текст из Safari и вставляете его в Notes, перетаскиваете файл из Finder в Telegram или скидываете фото через AirDrop. Эта магия кажется пользователю простой, но для разработчика за ней стоит сложная задача: как объяснить системе, что ваши кастомные данные тоже умеют «путешествовать»? В iOS 16 компания Apple представила ответ - протокол Transferable, ставший основой фреймворка Core Transferable. Это не просто еще один API, а декларативный мост, который навсегда меняет подход к реализации drag&drop, шеринга и других операций передачи данных.
Эволюция обмена данными:
До появления Transferable реализация перетаскивания или копирования кастомных объектов была квестом. Разработчику приходилось вручную работать с низкоуровневыми API вроде NSItemProvider, конвертировать свои модели в примитивные типы (String, Data, URL), писать кучу императивного кода для экспорта и импорта, а также обрабатывать множество состояний и ошибок.
Transferable переворачивает эту парадигму. Теперь вы декларируете возможности вашего типа прямо в его расширении, отвечая на вопрос системы: «Как я могу представить себя для передачи?». Система сама берет на себя всю тяжелую работу по управлению жизненным циклом передачи, взаимодействию с системными контроллерами и обработке ошибок.
TransferRepresentation: язык, на котором ваши данные говорят с системой:
Сердце протокола - свойство transferRepresentation. Это перечисление доступных представлений вашего типа для разных сценариев. Ключевая мощь в том, что вы можете предложить системе несколько вариантов одновременно, и она выберет оптимальный.
Один раз объявил - получил все:
После того как вы реализовали Transferable, ваша модель автоматически получает суперспособности во всех контекстах, где SwiftUI или система используют этот протокол:
Core Transferable и протокол Transferable - это не просто техническое обновление, а смена парадигмы в разработке под экосистему Apple. Они переводят сложную, императивную и подверженную ошибкам логику передачи данных на уровень декларативных моделей.
Главная особенность в согласованности и надежности. Вы один раз описываете, как ваш тип данных может представлять себя миру и эта декларация начинает работать универсально: в вашем собственном UI, в системных диалогах шеринга, при перетаскивании между приложениями и даже между устройствами через Continuity.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍10 2❤1🙏1
Forwarded from Кот Денисова
Искусственный интеллект сегодня - это как мощный спортивный автомобиль. В руках гонщика он выигрывает гонки. В руках новичка - разбивается о первое же дерево.
Споры об ИИ в разработке часто скатываются в крайности: от «он все сделает за меня» до «это полная ерунда». Давайте разберемся, как на самом деле стоит использовать эти инструменты, чтобы они стали рычагом для роста, а не костылем, ведущим к профессиональной деградации.
Сценарий 1 - ИИ как супер поисковик и генератор гипотез:
Представьте, вы столкнулись с ошибкой, которую не можете воспроизвести локально. Логи бессмысленны, а поисковик выдает все, кроме нужного. Вот где ИИ идеально подойдет.
ИИ с первого раза не даст точный ответ, но предложит 5-7 правдоподобных гипотез для проверки. Вы проверите их за 15 минут, вместо 2 часов бесплодного поиска. Это ускорение процесса дебага, а не его замена.
Сценарий 2 - ИИ как черная дыра для вашей экспертизы:
Самая большая ловушка - использовать ИИ для генерации кода, который вы не понимаете дословно. Ваше главное конкурентное преимущество - не скорость написания кода, а способность поддерживать, отлаживать и объяснять его. Слепо доверяя ИИ, вы это преимущество добровольно отдаете.
Золотые правила работы с ИИ для разработчика:
Что остается неизменным:
Искусственный интеллект - не угроза для хорошего разработчика. Это мощный помощник. Угроза в лени и нежелании разбираться в сути. Используйте ИИ, чтобы снять рутину и расширить кругозор, но никогда, чтобы избежать необходимости думать.
Please open Telegram to view this post
VIEW IN TELEGRAM
💯16👍6🔥4❤2🙏2👀1
Управление памятью в Swift - одна из тех тем, которую все проходят, но немногие действительно понимают. Особенно это касается Automatic Reference Counting (ARC). Мы привыкли думать о нем как о волшебном сборщике мусора, который где-то там, в недрах системы, следит за нашими объектами. Но реальность намного интереснее и прозаичнее. ARC - это не рантайм-система, а компиляторная технология, и именно в этом кроется большинство недоразумений.
Компилятор как главный архитектор памяти:
Представьте себе архитектора, который проектирует дом. Он не строит его сам, для этого есть строители. Но он создает детальные чертежи, где каждая балка, каждая электрическая цепь, каждая труба имеет свое место. ARC в Swift - именно такой архитектор. Когда вы пишете:
class User {
let name: String
init(name: String) { self.name = name }
}
func createUser() {
let user = User(name: "Алексей")
// что-то делаем с user
}ARC на этапе компиляции анализирует этот код и вставляет инструкции управления памятью. Грубо говоря, после компиляции код выглядит примерно так (в псевдокоде):
func createUser() {
let user = User(name: "Алексей") // objc_retain(user)
// что-то делаем с user
// objc_release(user) - здесь, при выходе из области видимости
}Ключевой момент: ARC не следит за объектами во время выполнения программы. Он не активный участник рантайма. Вся его работа заканчивается в момент компиляции. Он просто расставляет вызовы функций retain и release в правильных местах.
Рантайм - слепой исполнитель:
Если ARC - архитектор, то рантайм - строительная бригада, которая работает строго по чертежам. Ее задача предельно проста: выполнять инструкции.
Когда рантайм видит objc_retain(ptr), он увеличивает счетчик ссылок в заголовке объекта. Когда видит objc_release(ptr) - уменьшает. Когда счетчик достигает нуля - немедленно вызывает деструктор и освобождает память.
Важное уточнение: счетчик ссылок - это не абстракция Swift. Это физическое поле в заголовке объекта в куче памяти. Вы не можете получить к нему доступ из Swift-кода, потому что это низкоуровневая деталь реализации Objective-C runtime, который Swift использует под капотом на Apple-платформах.
Autorelease - не то, что вы думаете:
Слово autorelease вызывает самые странные ассоциации. «Автоматическое освобождение»? «Отложенный сборщик мусора»? На самом деле, это просто еще одна инструкция, которую ARC может вставить.
Autorelease не освобождает память. Он говорит: «Не делай release сейчас, сделай его позже, когда завершится текущий autorelease pool».
Это нужно в двух основных случаях:
Но вот что действительно важно: autorelease pool - это не магический контейнер, который хранит объекты. Это просто очередь release-операций, выполнение которой отложено.
В чистом Swift-коде autorelease используется все реже. Компилятор становится умнее и может определить момент release точнее. Но он все еще нужен для совместимости с Objective-C и некоторых случаях.
ARC в Swift - это не магия и не активный сборщик мусора. Это компиляторная технология, которая превращает высокоуровневый Swift-код в низкоуровневые инструкции управления памятью. Ее работа заканчивается в момент компиляции. Все, что происходит во время выполнения - просто механическое выполнение этих инструкций рантаймом.
Понимание этого разделения ответственности критически важно. Оно объясняет, почему одни оптимизации памяти работают, а другие нет. Почему autorelease pool важен в одних контекстах и бесполезен в других. Почему вы не можете «посмотреть» счетчик ссылок из Swift.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Разработчики под iOS хорошо знают: чем серьезнее проект, тем дольше он собирается. Добавил пару строк - жди. Запустил сборку на CI - опять жди. В Xcode 26 появился механизм, который пытается разорвать этот порочный круг - Compilation Cache.
В чем проблема:
Каждый день в команде происходит одно и то же. Несколько разработчиков работают в параллельных ветках. CI-сервер пересобирает каждый пул-реквест с нуля. Одни и те же зависимости и внутренние модули компилируются снова и снова. Большая часть этой работы - лишняя.
DerivedData не всегда решал эту задачу. Он был временным хранилищем, которое при проблемах советуют просто удалить. Это удобно для локальной отладки, но не дает никаких гарантий для переиспользования сборок.
Что предлагает Compilation Cache:
Начиная с Xcode 26, результаты компиляции можно сохранять в кэш осмысленно и с возможностью переиспользования. Ключевое изменение: Xcode теперь сам решает, можно ли переиспользовать результат компиляции, основываясь на том, что именно изменилось. Если исходные файлы, настройки компилятора или тулчейн не поменялись - работа не повторяется, а результат берется из кэша.
Особенно заметно это при переключении между ветками и при чистых сборках, когда кэш уже прогрет.
Как включить:
Достаточно добавить в настройки сборки:
COMPILATION_CACHE_ENABLE_CACHING = YES
После этого кэш будет накапливаться по мере компиляции.
Где разница будет заметна:
Почему не всем станет сильно быстрее:
Компиляция - не единственная стадия сборки. Обработка ассетов, копирование файлов, скриптовые фазы (линтеры, генерация кода), линковка и встраивание - все это может оставаться узким местом. Если сборка тормозит из-за них, кэш компиляции не поможет.
Compilation Cache - одно из самых практичных улучшений производительности в Xcode за последнее время. Он не исправит все медленные сборки и не заменит хорошую организацию проекта, но он решает конкретную и очень дорогую проблему - повторную компиляцию того, что уже было скомпилировано.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤20👍11🔥3🙏1🤝1 1
Привет! Нашел интересную статью, в которой автор рассказывает, как они адаптировали архитектуру под крупный проект с навигацией на UIKit и интерфейсом на SwiftUI. Главная цель - избавить разработчика от головной боли при работе с многопоточностью, оставив только верстку и бизнес-логику.
Что взяли за основу:
Из MVVM оставили Model, View, ViewModel. Из TCA добавили State, Action и Reducer.
Как упростили работу с дочерними вью:
Если у дочерней вью много входных параметров, их выносят в структуру ViewState внутри самой вью. Вместо длинного инициализатора - одна строка.
Аналогично с замыканиями: вместо десятка отдельных замыканий - один enum Action и одно замыкание onAction. Внутри вью просто вызывается onAction с нужным кейсом.
Для списков с разными ячейками - передают в List сразу весь State и Reducer. Внутри уже выбирают нужные данные для каждой ячейки.
Архитектура работает и со SwiftUI, и с UIKit - разница только в механизме отслеживания изменений State.
Автор предлагает гибридный подход, который сочетает простоту MVVM и стройность TCA. Основные плюсы: чистый код, отсутствие лишних асинхронных конструкций, удобная работа с дочерними вью и поддержка обеих UI-фреймворков (UIKit и SwiftUI). Полный код можно посмотреть на GitHub.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
В мире разработки часто возникает дискуссия: как оценить эффективность алгоритма? Можно измерить время выполнения на конкретных данных, но эти цифры будут относительными - зависеть от мощности железа, текущей нагрузки и множества других факторов. Существует более фундаментальный способ, который абстрагируется от конкретных измерений и описывает суть поведения алгоритма. Этот язык называется Big O нотация, и его понимание - не академическое упражнение, а практический навык, который отделяет хаотичное написание кода от осознанного проектирования систем.
Суть нотации - описываем не секунды, а характер роста:
Представьте, что вам нужно доставить письмо. Вы можете пройти пешком (медленно, но скорость не зависит от расстояния до почтового ящика), доехать на велосипеде (быстрее, скорость линейно зависит от расстояния) или отправить курьера, который будет обходить все дома в районе (время выполнения растет квадратично с увеличением количества адресов).
Big O - это именно про характер роста требуемых ресурсов (времени или памяти) при увеличении объема входных данных. Обозначение O(n) говорит: время работы растет пропорционально n. O(1): время не зависит от размера данных. Нотация игнорирует константы (O(2n) это O(n)) и менее значимые слагаемые, фокусируясь на доминирующем факторе при стремлении n к бесконечности.
От простого к сложному - иерархия сложностей в действии:
Big O нотация - это не просто набор странных символов для прохождения собеседований. Это система мышления, которая позволяет оценивать последствия ваших архитектурных решений на этапе проектирования.
Она отвечает на критически важный вопрос: «Что произойдет с моим приложением, когда данных станет в 100, 1000 или 1000000 раз больше?» Пренебрежение этим анализом ведет к созданию систем, которые корректно работают на тестовых данных, но непредсказуемо ведет себя при реальной работе, создавая инциденты, которые невозможно быстро разрешить простым добавлением ресурсов на сервере.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍9🙏2🔥1👀1🤝1
В SwiftUI раскрывающиеся списки - штука коварная. В обычном VStack или LazyVStack анимация работает как по маслу: нажал - контент плавно появился, исчез - так же плавно скрылся. Но стоит положить такую конструкцию в List, и анимация начинает дергаться. Контент просто выскакивает, а высота ячейки меняется рывками.
Почему в List анимация ломается:
Проблема в том, что List по-своему управляет переиспользованием ячеек и вычислением их высоты. Когда внутри ячейки появляется или исчезает условный блок с if, List не всегда корректно анимирует изменение размера. SwiftUI просто не понимает, как плавно перейти от одного состояния к другому.
DisclosureGroup - встроенное решение от Apple. Оно работает плавно, но не дает кастомизировать анимацию. Если вам нужен свой дизайн (своя иконка, свои тайминги), DisclosureGroup не подходит.
Как это можно обойти:
Есть способ, который заставляет List анимироваться так, как нужно. Идея в том, чтобы анимировать не появление/исчезновение контента, а его высоту. Для этого используется протокол Animatable, который анимирует одно числовое значение от 0 до 1. В зависимости от этого значения меняется высота блока, а сам контент всегда присутствует в иерархии, но его прозрачность и положение привязаны к анимируемому значению.
Основные шаги:
В результате List видит только изменение высоты ячейки и плавно анимирует ее, а контент появляется и исчезает синхронно.
Анимация раскрывающихся ячеек в SwiftUI List - не магия, а четкое понимание того, как List обрабатывает изменения высоты. DisclosureGroup решает проблему из коробки, но ограничивает в дизайне. Кастомное решение через Animatable сложнее, зато дает полную свободу. Выбор зависит от того, что важнее: скорость реализации или точное соответствие дизайну.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18 8🙏2❤1🔥1
Нашел интересную статью, в которой автор провел сравнение производительности SwiftUI и UIKit в iOS 26. На WWDC25 компания Apple уверяла, что с производительностью в SwiftUI стало в разы лучше. Но так ли это на практике? Чтобы проверить, он создал максимально сложную ленту и сравнил, как с ней справляются оба UI-фреймворка.
Что тестировали:
Лента содержала следующие элементы:
Все это заставляло экран работать на 120 кадрах в секунду, давая на каждый кадр всего 8 миллисекунд.
Результаты тестов:
Даже в iOS 26 SwiftUI значительно уступает UIKit в производительности при работе со сложными, тяжелыми интерфейсами. В простых лентах разница может быть незаметна, но как только появляются анимации, гифки, сложная верстка и жесты - SwiftUI начинает проседать.
Интересно, что SwiftUI List внутри использует не обычный UICollectionView, а некую UpdateCoalescingCollectionView, что, видимо, и дает такую разницу. Плюс сама архитектура SwiftUI с пересчетом тела вьюх, диффингом и пересчетом layout добавляет накладные расходы, которых UIKit лишен.
Автор делает невеселый вывод: для сложных сценариев, где важна производительность, UIKit все еще вне конкуренции.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤23👍8🙏3 2🤔1👀1
Apple официально объявила о смене руководителя. Тим Кук, возглавлявший компанию с 2011 года, с 1 сентября передаст пост CEO Джону Тернусу, который сейчас отвечает за разработку аппаратного обеспечения. Кук останется председателем совета директоров.
Кто такой Джон Тернус:
Тернус пришел в Apple в 2001 году в команду продуктового дизайна. За 25 лет он прошел путь от инженера до старшего вице-президента по аппаратной инженерии. Под его руководством создавались iPad, AirPods, iPhone, Mac и Apple Watch. Он также отвечал за внедрение новых материалов, повышение надежности устройств и снижение углеродного следа.
Почему это важно:
Тернус - инженер до мозга костей. Его назначение сигнализирует, что Apple делает ставку на инновации в аппаратной части. При нем вышли MacBook Neo, iPhone Air, были внедрены 3D-печать титана и новые композитные материалы. В отличие от Кука, который был операционным гением, Тернус - инженер, прошедший все стадии создания продуктов.
Мое мнение:
Тим Кук был человеком стабильности. При нем Apple почти не рисковала, редко вводила по-настоящему новые продукты и в основном полировала то, что придумали до него. Да, компания стала в разы богаче, но инноваций, которые меняли бы рынок, за его правление было очень мало. Я надеюсь, что с приходом Тернуса что-то изменится. Хочется верить, что Apple снова начнет удивлять и выпускать действительно новые, интересные продукты, а не просто обновлять айфоны и цвета их корпуса каждый год. Посмотрим, оправдаются ли надежды.
Apple меняет руководителя впервые за 15 лет. Это событие, но не революция. Тернус - свой человек, его знают и уважают в компании. Кук остается в совете директоров, так что резкой смены курса ждать не стоит. Для пользователей это может означать больше инноваций в технической части устройств и возможно, меньше внимания к софту и сервисам. А я лично надеюсь, что Apple наконец-то перестанет бояться рисковать и начнет делать то, за что ее когда-то полюбили - за умение удивлять.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍9🤯3🔥1👀1🫡1
Суд в США постановил: Apple имеет право удалять приложения из App Store с указанием причины или без нее. Речь идет о деле стримингового сервиса Musi, который загружал музыку с YouTube, показывал свою рекламу и брал 5,99 доллара за ее отключение. Apple удалила приложение в 2024 году. Musi подала в суд, но проиграла - и не просто проиграла, а с запретом на повторное обращение и с оплатой судебных издержек Apple.
Что решил суд:
Судья отклонил иск с формулировкой, которая теперь станет прецедентом: лицензионное соглашение Apple прямо говорит, что компания может прекратить распространение приложения в любое время, по любой причине или без нее, направив уведомление. Musi не оспаривала, что уведомление получила. Значит, все законно.
Apple - частная компания и App Store - не общественная площадка. Она имеет право решать, что публиковать, а что удалять. Даже если вы потратили годы на разработку. Даже если у вас миллионы пользователей.
Почему это важно для разработчиков:
До этого решения у многих была иллюзия, что Apple не может просто взять и удалить приложение без веской причины. Что есть процедура, обжалование, шанс все исправить. Оказывается, может. И не обязана даже объяснять почему.
Конечно, на практике Apple обычно дает предупреждения, указывает на нарушения и дает время на исправление. Но теперь у нее есть юридически закрепленное право так делать не всегда.
Apple может удалить ваше приложение без объяснения причин. Это законно. Это закреплено в соглашении, которое вы подписали. И теперь это подтверждено судом. Не нравится - не публикуйтесь в App Store. Но других легальных способов установить приложение на iPhone у вас нет.
А разработчикам из России - тем более стоит держать это в голове. Российские разработчики и так находятся в уязвимом положении: санкционные ограничения, проблемы с оплатой аккаунта, блокировки приложений по географическому признаку. Apple и без того может удалить приложение по формальным причинам - а теперь, как выяснилось, может и без всяких причин.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯16👀7👍4❤2💯1🗿1
Forwarded from Flutter & Dart | Мобильный трудоголик
В каждом проекте рано или поздно появляются серые, поблекшие импорты. Они висят, ни на что не влияют, но глаза мозолят. Ревьюеры тратят время на проверку, нужны ли они вообще. А кодовая база обрастает балластом, который никто не замечает, но всем мешает.
Одна команда, которая все решает:
В корне проекта достаточно выполнить:
dart pub get && dart fix --apply
Анализатор Dart пробежится по всем файлам, найдет неиспользуемые импорты и удалит их. Без лишних вопросов, без ручного перебора каждого файла.
Если хочется сначала посмотреть, что именно будет удалено, можно выполнить dart fix --dry-run. Покажет список изменений, но ничего не тронет.
Почему об этом вообще стоит думать:
Неиспользуемые импорты не ломают код, но они делают его грязным. Ревьюеры тратят время на проверку того, что на самом деле не используется. Линтеры и форматтеры работают хуже, когда списки импортов захламлены. А сам проект со временем становится тяжелее и менее понятным.
dart fix решает эту проблему мгновенно. Инструмент официальный, встроенный в экосистему Dart, так что никаких сторонних зависимостей тащить не нужно.
Что важно помнить:
Перед массовой чисткой лучше сделать коммит - мало ли что. Сгенерированные файлы (.g.dart) dart fix трогать не должен, они все равно перезапишутся при следующей сборке. И всегда после чистки стоит прогнать dart analyze && flutter test, чтобы убедиться, что ничего не сломалось.
dart fix --apply - это не магия, а просто правильный инструмент. Он не делает код быстрее и не добавляет новых фич. Зато он убирает мусор, который отвлекает, запутывает и создает иллюзию сложности. Если в вашем проекте есть неиспользуемые импорты - команда решит проблему за секунду. Если их нет - вы либо уже все почистили, либо просто не замечаете.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍6👀3🔥1🙏1🗿1
Недавно пользователи iPhone заметили странное: некоторые приложения получили обновления, но в описании указано не имя разработчика, а Apple. Текст гласит: «Это обновление от Apple улучшит функциональность этого приложения. Новые функции не добавлены».
Какие приложения пострадали:
В списке приложений: Candy Crush Soda Saga, Sentry Mobile, Catan Universe, Bluetti, Mortal Kombat, Duet Display, VLC и многие другие. Категории приложений совершенно разные: игры, утилиты, медиаплееры. Что их объединяет - непонятно.
Что говорят разработчики:
Один из разработчиков на Reddit сообщил, что Apple выпустила обновление его приложения с тем же номером версии и тем же содержимым, что и предыдущее. То есть технически ничего не изменилось, а обновление вышло.
Эксперты проанализировали код одного из таких приложений - и не нашли никаких изменений. Никаких исправлений уязвимостей, никаких новых функций, никаких правок.
Догадки:
Разработчики выдвигают несколько предположений:
Apple тихо, но уверенно обновляет приложения в App Store от своего имени. Что именно она меняет - неясно. Разработчики, чьи приложения попали под это, похоже, тоже не в курсе. Пока это выглядит как техническая необходимость, а не как злоупотребление. Но сам прецедент заставляет задуматься: Apple может влиять на приложения на вашем телефоне даже без участия их создателей.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯19🤔8👍4👀3❤1🙏1
Привет! Наткнулся на статью, где автор разбирает, почему List подходит не для всех случаев. Да, для однородных данных (например списка писем или задач) List незаменим. Но когда интерфейс становится сложнее - появляются разные типы карточек, нестандартные отступы, кастомные фоны - List начинает мешать. Специфичные модификаторы вроде listRowBackground или listRowInsets работают только внутри List и не дают гибкости.
Автор предлагает альтернативу - ScrollView с ленивыми стеками (LazyVStack / LazyHStack). За последние годы SwiftUI значительно подтянул их производительность. Если вы не отображаете сотни тысяч однородных строк, ScrollView - отличный выбор.
Что предлагает автор статьи:
Как это собирается вместе:
В итоговом экране автор использует ScrollingSurface как корневой контейнер, внутри - SectionedSurface с секциями, а внутри секций - DividedCard с NavigationLink. Все это покрывается кастомным стилем кнопки. API получается очень похожим на стандартный List, но с полным контролем над внешним видом.
Отказываться от List не нужно - он хорош для своих задач. Но когда интерфейс становится сложным и неоднородным, современный SwiftUI дает инструменты, чтобы построить свою замену. ScrollView с ленивыми стеками и Container View API позволяют создавать переиспользуемые компоненты, которые не уступают List в производительности, но дают полный контроль над дизайном. Если ваш интерфейс перерос стандартный List - присмотритесь к этому подходу.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17 9🙏3❤1👀1