Друзья, Apple продолжает сближать UIKit и SwiftUI! В iOS 26 обе технологии получают мощные обновления навигации, которые избавят нас от кастомных решений и костылей.
Что нового в UIKit.
Подзаголовки в UINavigationItem:
// Базовый подзаголовок
let navItem = navigationItem
navItem.title = "Профиль"
navItem.subtitle = "Премиум аккаунт"
// Стилизованная версия
let attributedSubtitle = AttributedString(
"Активен до 25.12.2026",
attributes: AttributeContainer([
.foregroundColor: UIColor.systemGreen,
.font: UIFont.systemFont(ofSize: 12, weight: .medium)
])
)
navItem.attributedSubtitle = attributedSubtitle
Гибкий поиск с новыми вариантами размещения:
// Разные варианты поиска
searchController.searchBarPlacement = .integrated // Встроенный
searchController.searchBarPlacement = .integratedButton // Как кнопка
searchController.searchBarPlacement = .integratedCentered // Центрированный
Что нового в SwiftUI.
Подзаголовки в NavigationStack:
struct ProfileView: View {
var body: some View {
NavigationStack {
Text("Контент профиля")
.navigationTitle("Профиль")
.navigationSubtitle("Премиум аккаунт") // Новое в iOS 26!
}
}
}
Liquid Glass для навигации:
.navigationBarTitleDisplayMode(.large)
.background(.ultraThinMaterial) // Эффект стекла
iOS 26 делает навигацию единой для UIKit и SwiftUI. Больше не нужно выбирать между технологиями, можно создавать современные интерфейсы используя нативные API обеих платформ.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Создание миниатюр - одна из самых распространенных задач в мобильной разработке. Но не все методы одинаково эффективны. Рассмотрим, как разные подходы показывают себя на практике при работе с 12-мегапиксельным JPEG.
Классические методы показывают разную производительность:
🔹 NSImage на macOS: 710 мс.
🔹 UIGraphicsImageRenderer на iOS: 210 мс.
🔹 UIImage.prepareThumbnail() на iOS: 130 мс.
Специализированные методы демонстрируют лучшие результаты:
🔹 CGImageSource на macOS: 16-26 мс.
🔹 CGImageSource на iOS: 24-95 мс в зависимости от формата.
Пример использования CGImageSource:
let source = CGImageSourceCreateWithData(imageData as CFData, nil)!
let cgThumb = CGImageSourceCreateThumbnailAtIndex(source, 0, [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: max(size.width, size.height)
] as CFDictionary)!
let thumbnail = UIImage(cgImage: cgThumb) // или NSImage в macOS
Ключевые параметры:
🔹 kCGImageSourceCreateThumbnailFromImageAlways: гарантирует создание миниатюры.
🔹 kCGImageSourceCreateThumbnailWithTransform: учитывает ориентацию изображения.
🔹 kCGImageSourceThumbnailMaxPixelSize: задает максимальный размер.
Получение информации о размерах:
let source = CGImageSourceCreateWithData(data as CFData, nil)!
if let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [CFString: Any],
let width = properties[kCGImagePropertyPixelWidth] as? Int,
let height = properties[kCGImagePropertyPixelHeight] as? Int {
print("Ширина: \(width), высота: \(height)")
}
Преимущества CGImageSource:
🔹 Мгновенное получение размеров изображения (2-4 мс).
🔹 Работа с различными форматами (HEIC, JPEG, PNG).
🔹 Эффективное использование памяти.
🔹 Поддержка последовательной загрузки.
CGImageSource показывает стабильно высокую производительность на обеих платформах, особенно заметно ускорение на macOS: до 40 раз по сравнению с классическими методами. Для задач, связанных с отображением галерей или списков изображений, этот подход становится оптимальным выбором.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Друзья, давайте честно: написание кода - это самая приятная, но далеко не самая большая часть нашей работы. Сегодня хочу поделиться типичным сценарием, который повторяется в проектах снова и снова.
Цикл разработки, который знаком каждому:
Неделя 1: начало разработки.
Вы получаете задачу, погружаетесь в контекст, продумываете архитектуру и бодро пишете код. Все идет по плану, фича почти готова. Вы чувствуете удовлетворение от хорошо сделанной работы и отправляете задачу на тестирование.
Неделя 2: ожидания тестирования.
Отдел тестирования перегружен, ваша задача висит в статусе «готова к тестированию». Вы переключаетесь на другие задачи и проекты, постепенно забывая детали реализации. Контекст стирается, а энтузиазм угасает.
Неделя 3: неожиданное возвращение.
Внезапно приходит сообщение: «Задача возвращена на доработку». Оказывается, требования изменились, нашли краевой случай или продукт-менеджер придумал улучшение. Теперь вам нужно заново вникать в задачу, которую вы уже считали завершенной.
Немного статистики:
🔹 Каждая третья фича возвращается на доработку минимум один раз.
🔹 15% задач требуют кардинальных изменений после тестирования.
🔹 Среднее время ожидания тестирования: от 2 дней до 7 дней.
🔹 Большинство разработчиков одновременно ведут несколько задач.
Почему так происходит:
Бизнес-требования постоянно эволюционируют: рынок не стоит на месте. То, что было актуально месяц назад, сегодня может устареть. Пользователи дают обратную связь, которая подсвечивает неочевидные проблемы. Тестирование выявляет ситуации, которые невозможно было предвидеть на этапе проектирования.
Как с этим работать:
Ментальные практики:
🔹 Не привязываться эмоционально к написанному коду.
🔹 Воспринимать изменения не как неудачу, а как возможность сделать продукт лучше.
🔹 Понимать, что выпиливание фичи - это не личное поражение, а забота о пользователе.
Построить рабочие процессы:
🔹 Организовать регулярные встречи с продукт-менеджерами для синхронизации.
🔹 Проводить промежуточные демо для стейкхолдеров до финального тестирования.
🔹 Выполнить детальные чек-листы перед сдачей задачи.
🔹 Назначить четкие критерии приемки для каждой фичи.
Процесс разработки - это живой организм, который постоянно меняется. Умение адаптироваться, сохранять гибкость и не терять энтузиазм в цикле бесконечных доработок - вот что отличает профессионала.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤14🙏10👀6🤝2 1
Привет, друзья! Сегодня поговорим о нововведения в Xcode 26.1 beta, которые повлияют на нашу повседневную работу:
SPM стал чуть умнее.
Локальное кэширование пакетов из реестра на час - это мелкое, но важное улучшение. Представьте: у вас в команде 10 человек, и все одновременно запускают pod install после обновления версии зависимости. Раньше каждый качал одно и то же, нагружая сеть. Теперь первый, кто скачал, становится локальным «источником» на час. Мелочь, а приятно, особенно для больших команд.
Instruments снова в строю.
На новых устройствах отказывал работать Processor Trace. Теперь это починили. Для тех, кто занимается глубокой оптимизацией и профилированием, это огромное облегчение. Теперь не нужно держать под рукой старый девайс, чтобы найти узкое место в производительности.
Coding Assistant перестал жрать память.
У кого были проекты с гигантскими git-репозиториями (например, с кучей субмодулей), тот знает, как Coding Assistant мог превратить MacBook в печку. Улучшение потребления памяти - это не про «удобства», это про возможность вообще работать с этим инструментом на реальных проектах.
Симулятор перестал чудить с JSON.
Команда simctl list devices --json снова работает корректно. Казалось бы, ерунда. Но это большая ерунда для всех, кто завязал на нее свои CI/CD-скрипты для автоматического тестирования на разных типах девайсов. Скрипты снова стали предсказуемыми.
Известные проблемы: будьте осторожны!
А вот здесь классика жанра. Apple выпускает бету, но перекладывает часть проблем на нас.
🔹 Симуляторы не запускаются. Первая сборка может упереться в то, что симулятор не загрузится.
Решение: Apple рекомендует вручную выполнить в терминале:
xcrun simctl runtime dyld_shared_cache update --all
🔹 Coding Assistant все еще подводит. Инструмент поиска по файлу может возвращать неверные номера строк. Представьте: вы хотите заменить все вхождения oldVariable на newVariable, а он из-за сбитого номера строки меняет не то, что нужно, и ломает вам логику. Пока что на этот инструмент лучше не полагаться в критичных операциях.
Xcode 26.1 beta - это типичный «качельный» апдейт. С одной стороны, мы видим долгожданные и очень точечные фиксы старых проблем (особенно в Instruments и SPM), которые реально облегчают жизнь. С другой получаем новые сюрпризы, которые могут остановить работу.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Вместе с выходом Swift 6.2 незаметно для многих произошли важные изменения в системе управления пакетами. Те, кто уже обновился, могли заметить, что сборки стали стабильнее, а некоторые процессы быстрее. Давайте разберемся, что именно изменилось и как это повлияет на вашу повседневную работу.
Безопасность памяти теперь под контролем.
Одно из ключевых нововведений: возможность включения строгой проверки безопасности памяти прямо в настройках пакета. На практике это означает, что потенциально опасные операции с памятью будут обнаруживаться на этапе компиляции, а не в рантайме.
Полезно для:
🔹 Серверных приложений.
🔹 Финансовых проектов.
🔹 Систем с повышенными требованиями к надежности.
Макросы перестали тормозить сборку.
Если вы используете макросы вроде
@Observable или создаете собственные, теперь можете рассчитывать на ускорение сборки до 30%. Система научилась использовать предварительно собранные компоненты вместо постоянной перекомпиляции зависимостей.Особенно заметно в CI/CD: в некоторых случаях экономия времени достигает нескольких минут на каждой сборке.
Умное кеширование экономит время.
Теперь бинарные зависимости кешируются более эффективно. При работе с несколькими проектами, использующими общие библиотеки, система не будет скачивать их повторно для каждого репозитория.
Когда полезно:
🔹 При работе в монорепозитории.
🔹 При частых пересборках.
🔹 При одновременной разработке нескольких связанных проектов.
Гибкие настройки диагностики.
Появилась возможность тонкой настройки предупреждений компилятора для разных компонентов проекта. Можно постепенно вводить строгие проверки в легаси-проектах, не ломая всю сборку сразу.
Обновление принесло именно те улучшения, которых не хватало многим разработчикам. Сборки стали значительно быстрее, работа с зависимостями удобнее, а контроль качества кода гибче. Особенно заметны эти изменения в больших проектах, где каждая минута сборки буквально на счету.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18 14🔥8 3👀2❤1👏1 1
Компания Apple запустила полноценную веб-версию App Store. Теперь можно искать и просматривать приложения со всех платформ Apple (iPhone, iPad, Mac, Apple Watch и Apple TV) прямо в браузере на любом устройстве.
Что изменилось?
Раньше ссылки на приложения вели на отдельные страницы с минимумом информации. Теперь это полнофункциональный магазин в браузере с:
🔹 Единым каталогом всех приложений.
🔹 Вкладкой Today с подборками и историями.
🔹 Разделами игр и Apple Arcade.
🔹 Полноценными страницами приложений со скриншотами, описаниями и видео.
Почему это важнее, чем кажется:
🔹 Кроссплатформенный поиск: теперь можно найти приложение, которое доступно одновременно на iPhone, iPad и Mac, и увидеть все варианты на одной странице. Больше не нужно переключаться между устройствами.
🔹 Обмен ссылками стал проще: отправляешь знакомому ссылку на полезное приложение и он может сразу посмотреть его описание и скриншоты, даже если у него под рукой только Android-телефон или ПК.
🔹 Маркетинг для разработчиков: теперь можно делиться ссылками на приложения в соцсетях, мессенджерах, на сайтах и пользователи увидят полноценную презентацию, а не урезанную карточку.
Этот шаг Apple не просто техническое обновление, а стратегический ход навстречу пользователям за пределами их экосистемы. Компания наконец-то признала реальность: миллионы людей используют смешанные устройства, например Windows с iPhone, и должны иметь возможность комфортно знакомиться с приложениями Apple.
Особенно важно, что веб-версия кардинально меняет процесс принятия решения о покупке. Теперь не нужно использовать iPhone или Mac, чтобы просто посмотреть, как выглядит приложение, достаточно открыть браузер на любом устройстве.
Для разработчиков это открывает новые возможности продвижения. Теперь можно эффективно работать с SEO и контент-маркетингом, направляя трафик напрямую в App Store из браузера. Пиар приложений выходит на новый уровень.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍12❤11😁5🤯2 2👏1
Привет! Сегодня хочу разобрать один из самых недооцененных инструментов в Swift: OptionSet. Это не просто протокол, а элегантное решение для задач, с которыми мы сталкиваемся почти в каждом проекте.
Для чего нужен OptionSet?
Представьте, что вы создаете компонент списка задач. В разных местах приложения вам нужно показывать разные возможности: где-то поиск и фильтр, где-то только сортировку, а в третьем месте вообще все элементы управления сразу.
Чаще всего, когда в коде нужно описать какие-то варианты выбора, разработчики сразу вспоминают про enum. Это действительно правильный подход для ситуаций, где может быть выбран только один вариан, например при статусах заказа: «в обработке», «доставляется» или «выполнен».
Но вот в чем проблема: когда нам нужно выбрать сразу несколько вариантов одновременно (например, показать и поиск, и фильтр, и сортировку), обычное перечисление не подходит. Пришлось бы создавать отдельные варианты для всех возможных комбинаций: «поиск_и_фильтр», «поиск_и_сортировка» и так далее. Это очень неудобно и громоздко.
OptionSet решает эту задачу гораздо элегантнее. Он работает как набор независимых переключателей, представьте себе чекбоксы на сайте. Вы можете включать и выключать их в любой комбинации и для этого не нужно заранее прописывать все возможные сочетания.
Пример.
Допустим, мы делаем тот самый список задач. Вот как может выглядеть наша конфигурация:
struct TasksListOptions: OptionSet {
let rawValue: Int
static let showFilter = TasksListOptions(rawValue: 1 << 0) // 0001
static let showSearch = TasksListOptions(rawValue: 1 << 1) // 0010
static let showSort = TasksListOptions(rawValue: 1 << 2) // 0100
static let showLayoutSelector = TasksListOptions(rawValue: 1 << 3) // 1000
}
Вся мощь OptionSet раскрывается, когда мы начинаем его использовать. Допустим, у нас есть экран «Сегодня» и экран «Все задачи». Для каждого из них мы можем легко задать нужный набор опций прямо при создании:
let todayOptions: TasksListOptions = [.showFilter, .showSearch]
let allTasksOptions: TasksListOptions = [.showFilter, .showSearch, .showSort, .showLayoutSelector]
// Для архива ничего не нужно
let archiveOptions: TasksListOptions = []
Теперь в коде это выглядит чисто и понятно. Когда мы создаем ViewModel для каждого экрана, мы просто передаем соответствующий набор опций:
let todayViewModel = TasksListViewModel(options: todayOptions)
let allTasksViewModel = TasksListViewModel(options: allTasksOptions)
let archiveViewModel = TasksListViewModel(options: archiveOptions)
Самое удобное, что мы можем легко проверять, какие опции активны в любой момент:
class TasksListViewModel {
let options: TasksListOptions
var shouldShowSearch: Bool {
return options.contains(.showSearch)
}
var shouldShowSort: Bool {
return options.contains(.showSort)
}
}
Технически, можно было бы использовать Set<Enum>, но зачем?
Приемущества OptionSet:
🔹 Производительность: работа на уровне битовых операций - это максимально быстро.
🔹 Минимальное потребление памяти: все флаги хранятся в одном числе.
🔹 Готовый API: contains, insert, remove, union и другие операции из коробки.
OptionSet - это один из тех инструментов, который кажется сложным только до первого использования. На практике он очень упрощает код, делает его безопаснее и выразительнее.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
В сети обнаружили любопытную функцию в тестовой версии RuStore для Android: возможность установки приложений на iPhone. Технология получила название RuStore Bridge, но ее реализация вызвала больше вопросов, чем восторгов.
Как это работает сейчас:
🔹 Нужен Android-смартфон с модифицированной версией RuStore.
🔹 iPhone подключается к Android-устройству по проводу.
🔹 Требуется использовать «Временный Apple ID» от разработчиков RuStore.
🔹 В каталоге пока только одно приложение: Промсвязьбанк, на котором можно опробовать работу данной технологии.
Ограничения:
🔹 Нужно удалить основную версию RuStore.
🔹 Кабели USB-C на USB-C не подходят, нужен кабель USB-A с переходником.
🔹 Авторизация только по SMS (аккаунты Яндекса и VK не поддерживаются).
Это важный, первый шаг, который показывает, что команда RuStore активно ищет решения для пользователей iOS. Да, текущая реализация выглядит сложной, но помните: все великие проекты начинались с прототипов.
Технология RuStore Bridge - это доказательство того, что российские разработчики не сдаются и продолжают инновации даже в сложных условиях. Тот факт, что они нашли способ обойти ограничения, уже заслуживает уважения.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍18🔥13👀8😁5❤3🤯2 1
Всем привет! Apple выпустила набор обновлений для App Store Connect, которые на первый взгляд кажутся минорными, но могут серьезно повлиять на наши рабочие процессы. Это не громкие анонсы, а скорее точечные улучшения, которые стоит иметь в виду.
Изменения в процессе ревью.
Теперь можно отправлять отдельные компоненты приложения на проверку, не дожидаясь завершения основного ревью. Например:
🔹 In-App Events, пока основная версия приложения еще на проверке.
🔹 Критический фикс, не связанный с текущими кастомными страницами.
🔹 Компоненты Game Center (достижения, таблицы лидеров) отдельно от основной сборки.
Это действительно упрощает жизнь, особенно когда нужно срочно пофиксить баг или запустить событие к определенной дате. Раньше такие ситуации превращались в долгое ожидание полноценной проверки.
Кастомные продуктовые страницы.
Лимит кастомных продуктовых страниц увеличен с 35 до 70. Но главное: теперь можно назначать ключевые слова для каждой страницы.
Например, если у вас приложение для редактирования фото, можно создать отдельные страницы для редактирования портретов (ключевые слова: «портрет», «ретушь»), обработки пейзажей (ключевые слова: «пейзаж», «природа»), создания коллажей (ключевые слова: «коллаж», «фоторедактор»).
Промо-коды для всех типов покупок.
Теперь промо-коды работают для всех типов In-App Purchases:
🔹 Consumable (потребляемые товары).
🔹 Non-consumable (непотребляемые покупки).
🔹 Non-renewing subscriptions (подписки без авто-продления).
Эти изменения показывают, что Apple постепенно делает экосистему более гибкой. Не революция, но эволюция в правильном направлении. Особенно радует расширение промо-кодов - это реально полезный инструмент для монетизации.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥15❤9 4 2🙏1🤝1
Всем привет! В мире Swift-разработки сегодня доминирует Swift Concurrency, но есть другой фреймворк, который заслуживает внимания: Combine. Этот инструмент способен кардинально изменить подход к работе с асинхронными операциями, предлагая совершенно иной взгляд на потоки данных.
Что такое Combine на самом деле:
Если просто - это декларативный способ работать с потоками данных. Вместо того чтобы вручную управлять очередями, колбэками и состоянием, вы описываете как данные должны преобразовываться и куда поступать.
Из чего состоит Combine:
🔹 Publisher: источник данных.
🔹 Subscriber: получатель данных.
🔹 Operator: фильтруют, модифицируют или комбинируют значения между Publisher и Subscriber.
Пример:
Представьте, что вы делаете поиск по товарам. Без Combine это обычно выглядело так:
🔹 Отслеживаем ввод в форму поиска.
🔹 Делаем небольшую задержку, чтобы не слать запросы на каждый символ.
🔹 Проверяем, что текст поиска не пустой.
🔹 Отправляем запрос.
🔹 Обновляем интерфейс в главной очереди.
Целая простыня кода с разрозненными таймерами и колбэками. С Combine это превращается в элегантную цепочку:
searchTextField
.publisher(for: \.text)
.debounce(for: .milliseconds(300), scheduler: RunLoop.main)
.removeNil()
.filter { !$0.isEmpty }
.flatMapLatest { query in
apiService.searchProducts(query: query)
.catch { _ in Just([]) }
}
.receive(on: DispatchQueue.main)
.sink { [weak self] products in
self?.updateUI(with: products)
}
.store(in: &cancellables)
Почему Combine все еще актуален.
Да, async/await проще для линейных операций. Но Combine незаменим, когда нужно:
🔹 Реагировать на непрерывные изменения (текст в поиске, положение слайдера).
🔹 Комбинировать несколько потоков данных.
🔹 Создавать сложные цепочки преобразований.
Главный плюс, который часто упускают: Combine учит думать о данных как о потоках. Это ментальная модель, которая пригождается даже при работе с Swift Concurrency.
Combine - это не просто фреймворк, а философия. Да, его изучение требует времени, но однажды изучив, вы начинаете видеть асинхронные операции в совершенно новом свете. Владение реактивным программированием - это важный навык для опытного iOS-разработчика, учитывая насколько широко оно применяется в крупных проектах и является стандартом во многих компаниях.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Друзья, сегодня поговорим о боли, знакомой каждому разработчику. Вы придумали гениальное техническое решение, но менеджер вас не понимает. В чем проблема? Мы говорим на разных языках!
Почему нас не слышат?
Бизнесу абсолютно не интересны:
Что действительно волнует бизнес.
Бизнес живет тремя ключевыми метриками:
Трансформируем технические аргументы в бизнес-выгоды:
Вместо: «Нужно переписать этот legacy-код, он ужасен».
Говорим: «Текущая архитектура платежного модуля приводит к 20 часам простоя в месяц. После рефакторинга мы сэкономим X и снизим риск финансовых потерь».
Вместо: «Давайте использовать новую библиотеку, она крутая».
Говорим: «Новая библиотека ускорит разработку новых фич на 40% и снизит количество багов на 60%».
Практический инструмент: формула презентации идеи.
Красные флаги в коммуникации.
Если в ответ на ваши обоснованные предложения вы слышите:
Это признаки токсичной среды, где вас воспринимают как исполнителя, а не партнера.
Что может помочь:
Результат таких изменений:
Умение говорить на языке бизнеса - это не предательство технических принципов, а мост между двумя мирами. Когда вы показываете, как технические улучшения влияют на прибыль и риски, ваши идеи начинают слышать.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤9 4🤔2🔥1
Хочу порекомендовать канал @prettygeeknotes Анна Жарковой. Много полезного контента, посвященного мобильной разработке, полезные гайды, статьи, новости, а также анонсы важных IT-мероприятий. Кстати, Анна автор книги "Kotlin Multiplatform на практике"
Советую подписаться 👍
Советую подписаться 👍
🔥14👍6🗿6😁5❤3 1 1
Обнаружилась серьезная проблема в Xcode 26.1: симулятор iOS 26.1 может дико тормозить и грузить процессор на 100%. Если у вас тоже бешено крутятся кулеры и симулятор работает как в слайд-шоу, вы не одиноки.
В чем проблема:
Процесс MercuryPosterExtension постоянно крашится, что заставляет систему запускать ReportCrash снова и снова. Это создает бесконечный цикл падений и отчетов об ошибках, который съедает все ресурсы процессора.
Откуда растут ноги:
Судя по логам, проблема в работе с обоями (PosterKit) в симуляторе. Когда система пытается отобразить стандартные обои происходит сбой.
Рабочие решения:
🔹 Перейти на симулятор iOS 26.0, он работает стабильно.
🔹 Сменить обои в симуляторе: зайти в настройки, выбрать другие обои и удалить стандартные, черные.
Это классический пример того, как мелкий баг в одном компоненте может парализовать всю работу. Особенно обидно, когда срочно нужно тестировать на последней версии iOS, а симулятор превращается в слайд-шоу.
Что удивительно: проблема сохраняется и в Xcode 26.2 beta. Похоже, Apple еще не успела пофиксить эту проблему.
Ждем фикс от Apple.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Apple представила в iOS 26 технологию, которая может кардинально изменить подход к локализации приложений. Language Discovery - это не просто очередное API, а фундаментальный сдвиг в том, как системы понимают языковые предпочтения пользователей.
Что было раньше:
До iOS 26 мы работали с примитивным API:
let userLanguages = Locale.preferredLanguages
// ["en-US", "es-MX", "fr-CA"]
Это создавало три основные проблемы:
🔹 Только строковые идентификаторы без контекста.
🔹 Пользователи вручную добавляли языки в настройках.
🔹 Не было понимания реальных языковых привычек.
Что изменилось:
Language Discovery анализирует реальное поведение пользователя:
🔹 На каких языках он печатает в сообщениях и почте.
🔹 Какой контент потребляет (музыка, подкасты, статьи).
🔹 В каких приложениях и на каких языках работает.
Все это происходит локально на устройстве с сохранением приватности.
Новое API:
Новое API Locale.preferredLocales возвращает богатые объекты с полной информацией о локали:
🔹 Язык и регион.
🔹 Систему чисел и валюту.
🔹 Направление письма (RTL/LTR).
🔹 Календарную систему.
Пример:
Вместо алфавитного списка из 100+ языков теперь можно показывать умный выбор:
class SmartLanguagePickerManager: ObservableObject {
@Published var preferredLanguages: [LanguageItem] = []
@Published var otherLanguages: [LanguageItem] = []
// Языки, которые поддерживает наше приложение
private let supportedLocales = [
Locale(identifier: "en-US"),
Locale(identifier: "ru-RU"),
Locale(identifier: "de-DE")
]
func organizeLanguages() {
// Получаем предпочтения пользователя через новый API
let userLocales = Locale.preferredLocales
// Сортируем языки на релевантные и остальные
for locale in supportedLocales {
let item = LanguageItem(locale: locale, isPreferred: isRelevant(locale, userLocales))
if item.isPreferred {
preferredLanguages.append(item)
} else {
otherLanguages.append(item)
}
}
// Сортируем остальные языки по алфавиту
otherLanguages.sort { $0.displayName < $1.displayName }
}
private func isRelevant(_ locale: Locale, _ userLocales: [Locale]) -> Bool {
// Проверяем совпадение с предпочтениями пользователя
for userLocale in userLocales {
// Точное совпадение (en-US и en-US)
if locale.identifier == userLocale.identifier { return true }
// Совпадение по языку (en-US и en-GB)
if locale.language.languageCode == userLocale.language.languageCode { return true }
}
return false
}
}
struct LanguageItem: Identifiable {
let id = UUID()
let locale: Locale
let isPreferred: Bool
// Отображаемое название языка
var displayName: String {
locale.localizedString(forIdentifier: locale.identifier) ?? locale.identifier
}
}
Использование во View:
struct LanguagePickerView: View {
@StateObject private var manager = SmartLanguagePickerManager()
var body: some View {
List {
Section("Рекомендуемые языки") {
ForEach(manager.preferredLanguages) { language in
Text(language.displayName)
}
}
Section("Другие языки") {
ForEach(manager.otherLanguages) { language in
Text(language.displayName)
}
}
}
.onAppear {
manager.organizeLanguages()
}
}
}
Преимущества:
🔹 Автоматическое определение RTL без костылей.
🔹 Правильные форматы чисел и дат для каждой культуры.
🔹 Умное сопоставление локалей (en-US -> en-GB).
Пришло время пересмотреть подход к локализации. Вместо статических списков: умные системы, которые понимают культурный контекст. Вместо ручных настроек: автоматическое определение предпочтений. Особенно порадовало, что Apple сохранила приватность: все вычисления локальные.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 Это база 823 вопроса с собеседований на iOS разработчика. Теперь можно легко получить оффер, подготовившись к самым популярным вопросам 😏
😁10🔥5👍4🤔2❤1🗿1 1
Всем привет! Сегодня поговорим о боли каждого iOS-разработчика: долгая сборка проекта, которая крадет наше время, концентрацию и нервы.
Представьте: делаете небольшую правку в коде, ждете билд 3-5 минут -> проверяете -> снова правка -> снова ждете... За день набегают десятки потерянных минут!
Оказывается, можно ускорить процесс в разы без перехода на новый MacBook, главное найти «узкие места»:
Анализируем временную шкалу сборки (Build Timeline).
Запускаем чистый билд и смотрим Report Navigator, включаем Assistant. Видим наглядную диаграмму, где процессы идут параллельно, а где в порядке очереди.
Диаграмма покажет не просто общее время, а именно те этапы, которые выполняются последовательно вместо параллельного выполнения. Часто оказывается, что один медленный скрипт или компиляция большого файла блокируют всю остальную сборку, создавая эффект пробки.
Этот анализ - первый и самый важный шаг: без понимания где именно теряется время, все оптимизации будут слепыми. Вы узнаете, стоит ли бороться с компиляцией Swift, пересматривать скрипты или менять структуру модулей.
Оптимизируем Build Phases.
🔹 SwiftLint запускаем только для измененных файлов.
🔹 Генерацию кода запускаем только для релизных сборок.
🔹 Проверяем влияние пакетов Swift Packages на время сборки.
Включаем мониторинг медленного кода.
Добавляем в Other Swift Flags для Debug:
-Xfrontend -warn-long-function-bodies=100
-Xfrontend -warn-long-expression-type-checking=100
Компилятор покажет функции, где проверка типов занимает больше 100ms - часто это огромные SwiftUI view или сложные методы.
Настройка:
🔹 Шаг 1: запускаем Build Timing Summary (Product -> Perform Action -> Build with Timing Summary).
🔹 Шаг 2: смотрим, что больше всего тормозит: компиляция или скрипты.
🔹 Шаг 3: точечно оптимизируем самые медленные этапы.
🔹 Шаг 4: настраиваем автоматический мониторинг, чтобы проблемы не возвращались.
Оптимизация сборки - это не разовое мероприятие, а культура разработки. Каждая сэкономленная секунда, умноженная на количество билдов и разработчиков в команде, дает огромную экономию времени в долгосрочной перспективе.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Синглтоны - это классический паттерн, который есть почти в каждом iOS-проекте. Но в эпоху Swift Concurrency они превращаются в мину замедленного действия, потому что это глобальное состояние, доступное из любого потока.
Обычный синглтон - это класс, а классы в Swift по умолчанию не thread-safe (не потокобезопасны). Когда вы обращаетесь к синглтону из разных потоков или акторов, возможны гонки данных и непредсказуемое поведение.
Решение проблемы:
Есть несколько стратегий:
🔹
@MainActor
@MainActor
class ThemeManager {
static let shared = ThemeManager()
private init() {}
var currentTheme = "light"
func switchToDarkTheme() {
currentTheme = "dark"
// Здесь обновляем UI
}
}
Как это работает:
🔹
@unchecked Sendable
class CounterManager: @unchecked Sendable {
static let shared = NetworkManager()
private init() {}
// Используем NSLock для потокобезопасности
private let lock = NSLock()
private var count = 0
func increment() {
lock.lock()
count += 1
print("Count: \(count)")
lock.unlock()
}
}
// Использование:
CounterManager.shared.increment()
Это вариант для случаев, когда вы вручную обеспечиваете потокобезопасность через NSLock или подобные инструменты.
Для большинства проектов
@MainActor оказывается идеальным решением. Этот подход сочетает в себе простоту использования и надежную защиту от проблем с потоками.Другие варианты вроде кастомных акторов или ручных блокировок часто создают больше сложностей, чем решают проблем. Они требуют постоянного использования await или тщательной ручной синхронизации, что лишает синглтоны их главного преимущества - простоты.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Вышла новая версия официального расширения Swift для VS Code - 2.12.0. Если вы до сих пор не пробовали перейти с Xcode, сейчас самое время пересмотреть этот вопрос.
Что нового в версии 2.12.0:
Почему это важно для разработчиков:
Расширение Swift для VS Code особенно востребовано в нескольких сценариях:
Обновление расширения Swift для VS Code демонстрирует прогресс в развитии инструментов для Swift-разработки за пределами экосистемы Xcode. Новые функции, такие как интерактивный онбординг и улучшенная работа с тестами, делают среду более доступной как для новичков, так и для опытных разработчиков.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
По данным Bloomberg, Apple ведет переговоры с Google о сделке на $1 ИИ-модели Gemini для обновленной Siri. Это одно из самых неожиданных технологических партнерств года.
Что происходит:
🔹 Apple будет использовать 1.2 триллионную модель Google Gemini для новых функций Siri.
🔹 Сумма контракта около $1 миллиарда в год.
🔹 Обновленная Siri с кодовым именем Linwood выйдет весной 2026 года в iOS 26.4.
Технические детали:
Gemini будет отвечать за две ключевые функции:
🔹 Суммаризация: сжатие и обобщение информации.
🔹 Планирование: выполнение сложных многошаговых задач.
При этом основные функции Siri останутся на собственных моделях Apple. Важно: все вычисления будут происходить на серверах Apple Private Cloud Compute без доступа Google к пользовательским данным.
Почему это важно:
🔹 Признание отставания: Apple официально признает, что отстала в ИИ-гонке.
🔹 Временное решение: это временное решение, пока Apple не догонит по качеству.
🔹 Стратегический ход: лучше временное партнерство, чем полная потеря рынка.
Что будет дальше:
Apple уже разрабатывает собственную модель на 1 триллион параметров и надеется заменить Gemini уже в 2026 году, но догнать Google, которая постоянно улучшает Gemini, будет непросто.
Это напоминает ситуацию с поиском в Safari, где Google платит Apple миллиарды за статус поиска по умолчанию. Теперь роли поменялись: Apple платит Google. Для пользователей это в целом хорошая новость: Siri станет значительно умнее.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
😁14🤯6🔥5👀2🫡1
Добрый день! Сегодня поговорим о том, как правильно готовить проекты к будущим обновлениям Swift. Оказывается, многие до сих пор мигрируют вручную, хотя Apple давно предоставила удобные инструменты.
Зачем это нужно?
Каждый год Swift становится лучше, но новые фичи часто ломают обратную совместимость. Вместо того чтобы тратить недели на ручную правку кода, можно использовать встроенные инструменты миграции.
Как это работает:
В настройках сборки Xcode есть секция «Upcoming Features». Там можно включить режим миграции для конкретной фичи:
🔹 Выбираете фичу из выпадающего списка.
🔹 Включаете Migrate вместо Enabled.
🔹 Собираете проект и изучаете замечания.
🔹 Применяете автоматические фиксы.
Пример.
Допустим, у вас есть код:
class DataProcessor {
func processData() async {
// Какая-то логика
}
}После включения миграции Xcode покажет предупреждение и предложит добавить
@concurrent: class DataProcessor {
@concurrent func processData() async {
// Теперь код готов к будущим изменениям
}
}Почему опасно мигрировать вручную:
Рассмотрим конкретный пример. Без миграционного инструментария вы можете не заметить, что ваш асинхронный метод внезапно начал выполняться на главном потоке, хотя раньше работал в фоне. Результат: тормозящий интерфейс и недовольные пользователи.
Преимущества автоматической миграции:
🔹 Безопасность: инструмент знает все нюансы изменений.
🔹 Скорость: минуты вместо дней/недель.
🔹 Обучение: каждое замечание содержит подробное объяснение.
🔹 Консистентность: правки в едином стиле по всему проекту.
Работает для Swift Package Manager.
Тот же подход работает и для пакетов через swift-settings в Package.swift:
.target(
name: "MyLibrary",
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency")
]
)
Swift Migration Tooling - это не просто удобная фича, а необходимость для поддержания кодовой базы в актуальном состоянии. Инвестируйте время в изучение этих инструментов, они окупятся многократно при следующем серьезном обновлении Swift.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Всем привет! Казалось бы, что еще нужно для счастья? Высокая зарплата, возможность работать удаленно, интересные задачи. Но многие из нас просыпаются с ощущением, что что-то не так. Давайте разберемся, что мешает нам чувствовать себя счастливыми в профессии.
Стирание границ между работой и жизнью.
Работа постепенно поглощает все: вечер перетекает в ночь, ноутбук лежит рядом с кроватью, мысли о багах не отпускают даже во сне.
Как решить данную проблему:
Отсутствие настоящего отдыха.
У многих разработчиков вообще нет хобби. Весь свободное время уходит на курсы, пет-проекты и изучение новых технологий, но это не отдых, а продолжение работы.
Как решить данную проблему:
Найдите занятие, которое не имеет практической пользы:
Социальная изоляция.
Удаленная работа лишает нас спонтанных разговоров у кофемашины, шуток в коридоре, простого человеческого общения.
Как решить данную проблему:
Синдром самозванца.
«Я недостаточно знаю», «Все вокруг умнее», «Мне просто повезло». Эти мысли знакомы почти каждому разработчику.
Как решить данную проблему:
Заведите журнал достижений и регулярно записывайте:
Постоянное сравнение с другими.
Соцсети создают иллюзию, что все вокруг запускают стартапы, путешествуют и достигают невероятных успехов.
Как решить данную проблему:
Хронический стресс.
Легаси-код, дедлайны, ночные релизы, баги в пятницу вечером - разработка это не только творчество, но и постоянный хаос.
Как решить данную проблему:
Отсутствие смысла.
Можно хорошо зарабатывать, работать с крутыми технологиями, но чувствовать, что твои усилия не меняют ничего важного.
Как решить данную проблему:
Нестабильный ритм жизни.
Дежурства, аварии, ночные правки, когда ты не контролируешь свое время, это подрывает нервную систему.
Как решить данную проблему:
Токсичная культура продуктивности.
Пока ты спишь, твой конкурент работает - этот подход выжимает все соки и приводит к выгоранию.
Отдых - это часть продуктивности. Мозг восстанавливается, когда вы ничего не делаете.
Страх просить о помощи.
Ментальное здоровье в ИТ до сих пор считается чем-то постыдным. Люди молчат, хотя внутри уже горят.
Обращение к психологу - это не слабость, а ответственность перед собой и проектом.
Счастье в программировании оказывается гораздо ближе к простым человеческим вещам, чем к технологиям или зарплате. Оно рождается там, где находится баланс между работой и личной жизнью, где есть место настоящему отдыху без чувства вины и живому общению без мессенджеров.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤20👍10👀4🔥2🙏1