Мобильный трудоголик
1.4K subscribers
61 photos
9 videos
269 links
👨‍💻 Пишу простым языком об iOS разработке на Swift и мобильной разработке в целом.
🔹 Вошел в IT задолго до того как это стало мейнстримом.
---
‍Обо мне: https://t.me/hardworkerIT/3
Чат: @hardworkerChatIT
Канал про разработку и жизнь в ИТ: @itDenisov
Download Telegram
🔨 Проблема с симулятором в Xcode 26.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
18👍128🙏5🤯3🔥1👀1
🔢 Language Discovery в iOS 26: умное определение предпочтительных языков пользователя.

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
17👍11🔥511
🔥 Это база 823 вопроса с собеседований на iOS разработчика. Теперь можно легко получить оффер, подготовившись к самым популярным вопросам 😏
😁10🔥5👍4🤔21🗿11
🔨 Ускоряем билд проекта в Xcode.

Всем привет! Сегодня поговорим о боли каждого 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
16👍15🔥73🙏1👀1
🔢 Синглтоны в Swift Concurrency: как избежать гонки данных.

Синглтоны - это классический паттерн, который есть почти в каждом 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
17🔥11👍72🙏11
💻 Swift в VS Code: официальный плагин стал еще лучше.

Вышла новая версия официального расширения Swift для VS Code - 2.12.0. Если вы до сих пор не пробовали перейти с Xcode, сейчас самое время пересмотреть этот вопрос.


Что нового в версии 2.12.0:

🔵Swiftly для управления тулчейнами: теперь можно легко устанавливать стабильные и snapshot-версии Swift прямо из редактора.

🔵Умные подсказки: система предлагает перезапустить SourceKit-LSP при изменении конфигурации.

🔵Улучшенное тестирование: можно отменять запущенные тесты и запускать их несколько раз.

🔵Онбординг для новичков: интерактивное руководство для тех, кто только начинает работать со Swift в VS Code.


Почему это важно для разработчиков:

Расширение Swift для VS Code особенно востребовано в нескольких сценариях:

🔵Серверная разработка на Swift: где не требуется Interface Builder и другие iOS-специфичные инструменты.

🔵Кроссплатформенные проекты: когда разработчики работают одновременно с несколькими платформами или языками программирования.

🔵Linux-среда: где Xcode недоступен, но нужна полноценная поддержка Swift.


🔗 VS Code Swift Extension 2.12.0 - Release Notes


💡 Вывод:

Обновление расширения Swift для VS Code демонстрирует прогресс в развитии инструментов для Swift-разработки за пределами экосистемы Xcode. Новые функции, такие как интерактивный онбординг и улучшенная работа с тестами, делают среду более доступной как для новичков, так и для опытных разработчиков.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍10🔥521👀1
🍎 ИИ-провал Apple: Siri получит мозги Gemini от Google.

По данным 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 Migration Tooling: правильная миграция Swift кода.

Добрый день! Сегодня поговорим о том, как правильно готовить проекты к будущим обновлениям 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
16👍8🔥3🙏1🤝11
Forwarded from Кот Денисова
👨‍💻 Жизнь за кодом: почему ИТ-специалисты зачастую несчастны.

Всем привет! Казалось бы, что еще нужно для счастья? Высокая зарплата, возможность работать удаленно, интересные задачи. Но многие из нас просыпаются с ощущением, что что-то не так. Давайте разберемся, что мешает нам чувствовать себя счастливыми в профессии.


Стирание границ между работой и жизнью.

Работа постепенно поглощает все: вечер перетекает в ночь, ноутбук лежит рядом с кроватью, мысли о багах не отпускают даже во сне.

Как решить данную проблему:

🔹Установите четкое время окончания рабочего дня.
🔹Не проверяйте рабочую почту и мессенджеры после 18:00.
🔹Создайте отдельное рабочее пространство, даже если работаете из дома.


Отсутствие настоящего отдыха.

У многих разработчиков вообще нет хобби. Весь свободное время уходит на курсы, пет-проекты и изучение новых технологий, но это не отдых, а продолжение работы.

Как решить данную проблему:

Найдите занятие, которое не имеет практической пользы:

🔹Рисование.
🔹Игра на музыкальном инструменте.
🔹Прогулки на природе.
🔹Рукоделие.


Социальная изоляция.

Удаленная работа лишает нас спонтанных разговоров у кофемашины, шуток в коридоре, простого человеческого общения.

Как решить данную проблему:

🔹Чаще общайтесь с друзьями и родными.
🔹Работайте время от времени из коворкингов.
🔹Посещайте митапы и конференции.
🔹Найдите офлайн-сообщества по интересам.


Синдром самозванца.

«Я недостаточно знаю», «Все вокруг умнее», «Мне просто повезло». Эти мысли знакомы почти каждому разработчику.

Как решить данную проблему:

Заведите журнал достижений и регулярно записывайте:

🔹Какие задачи решили.
🔹Чему научились.
🔹Какие проблемы преодолели.


Постоянное сравнение с другими.

Соцсети создают иллюзию, что все вокруг запускают стартапы, путешествуют и достигают невероятных успехов.

Как решить данную проблему:

🔹Отпишитесь от тех, кто вызывает зависть.
🔹Сравнивайте себя только с собой в прошлом.
🔹Помните: идеальные образы в соцсетях - это профессионально созданный контент.


Хронический стресс.

Легаси-код, дедлайны, ночные релизы, баги в пятницу вечером - разработка это не только творчество, но и постоянный хаос.

Как решить данную проблему:

🔹Планируйте день с запасом времени.
🔹Научитесь говорить нет новым задачам при полной загрузке.
🔹Регулярно занимайтесь спортом или хотя бы гуляйте.


Отсутствие смысла.

Можно хорошо зарабатывать, работать с крутыми технологиями, но чувствовать, что твои усилия не меняют ничего важного.

Как решить данную проблему:

🔹Участвуйте в опенсорс проектах.
🔹Станьте ментором для новичков.


Нестабильный ритм жизни.

Дежурства, аварии, ночные правки, когда ты не контролируешь свое время, это подрывает нервную систему.

Как решить данную проблему:

🔹Договаривайтесь о компенсационных выходных.
🔹Создайте четкие ритуалы завершения рабочего дня.
🔹После ночного дежурства обязательно отдыхайте.


Токсичная культура продуктивности.

Пока ты спишь, твой конкурент работает - этот подход выжимает все соки и приводит к выгоранию.

Отдых - это часть продуктивности. Мозг восстанавливается, когда вы ничего не делаете.


Страх просить о помощи.

Ментальное здоровье в ИТ до сих пор считается чем-то постыдным. Люди молчат, хотя внутри уже горят.

Обращение к психологу - это не слабость, а ответственность перед собой и проектом.


💡 Вывод:

Счастье в программировании оказывается гораздо ближе к простым человеческим вещам, чем к технологиям или зарплате. Оно рождается там, где находится баланс между работой и личной жизнью, где есть место настоящему отдыху без чувства вины и живому общению без мессенджеров.


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍10👀4🔥2🙏1
🔢 AutoreleasePool: когда ARC недостаточно для управления памятью.

Всем привет! Сегодня разберем механизм AutoreleasePool - наследие Objective-C, которое продолжает играть важную роль в управлении памятью Swift-приложений. Этот инструмент особенно актуален при работе с ресурсоемкими операциями.


Принцип работы AutoreleasePool:

AutoreleasePool функционирует как отложенный менеджер памяти. В отличие от немедленного освобождения объектов при выходе из области видимости, система собирает их в специальный пул. Очистка происходит при явном вызове drain() или по завершении текущего runloop-цикла.


Пример:


for i in 0..<5000 {
// Data работает с байтами (UInt8)
// Каждый элемент занимает 1 байт. 1024 * 1024 = 1 МБ
let data = Data(repeating: 0, count: 1024 * 1024) // 1 MB
processData(data)
}


В этом случае в памяти одновременно может находиться до 5 GB данных, поскольку объекты не уничтожаются до завершения цикла.


Оптимизированный подход:


for i in 0..<5000 {
autoreleasepool {
let data = Data(repeating: 0, count: 1024 * 1024) // 1 MB
processData(data)
}
}


Теперь каждый экземпляр Data уничтожается после итерации, сохраняя стабильное потребление памяти.


Исторический контекст и современность:

В Objective-C разработчики вручную управляли пулами через NSAutoreleasePool. Swift сохранил эту функциональность через синтаксис autoreleasepool {}, хотя в большинстве сценариев ARC успешно справляется самостоятельно.


Критические сценарии применения:

🔵Пакетная обработка медиафайлов: при последовательной обработке изображений или видео создание отдельных пулов для каждого файла предотвращает кумулятивное потребление памяти.
🔵Фоновые операции: в кастомных thread-ах, где отсутствует автоматический runloop, необходимо ручное управление пулами.
🔵Работа с Legacy-кодом: при интеграции старых Objective-C библиотек, активно использующих autorelease.


Подробные статьи:

🔵NSAutoreleasePool
🔵Управление памятью в Swift
🔵Что такое autoreleasepool?


💡 Вывод:

AutoreleasePool остается специализированным инструментом для оптимизации пикового потребления памяти. Его разумное применение особенно важно в высоконагруженных приложениях, где контроль за памятью напрямую влияет на производительность и стабильность приложения.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍11🔥531
🔢 Новые возможности UIColorPickerViewController в iOS 26.

С выходом iOS 26 разработчики UIKit получают расширенные возможности для работы с цветом, что особенно важно в эпоху HDR-дисплеев и повышенных требований к визуальному качеству приложений.


HDR-цвета в стандартных компонентах:

Одним из наиболее значимых обновлений стала поддержка HDR-цветов в UIColorPickerViewController и UIColorWell. Новое свойство maximumLinearExposure позволяет задавать максимальную яркость для цветов с расширенным динамическим диапазоном. Значение больше 1 активирует дополнительный слайдер «HDR Boost», дающий пользователям возможность тонко настраивать экспозицию выбранного цвета.

Это открывает новые горизонты для приложений, где важна точная цветопередача: графических редакторов, приложений для обработки фото, дизайнерских инструментов и любых продуктов, требующих работы с широким цветовым охватом.

Пример:

// Настройка пикера для профессиональной работы с цветом
let colorPicker = UIColorPickerViewController()
colorPicker.supportsEyedropper = true
colorPicker.maximumLinearExposure = 2.0 // Расширенный диапазон яркости

// Для UIColorWell в кастомных интерфейсах
let colorWell = UIColorWell()
colorWell.supportsEyedropper = true
colorWell.maximumLinearExposure = 1.8



Пипетка становится публичным API:

Свойство supportsEyedropper, ранее доступное только как приватный API в iOS 18, теперь официально документировано и доступно для использования. Эта функция позволяет включать или отключать инструмент «пипетка» в интерфейсе выбора цвета. При активации пользователи могут выбирать цвета напрямую с экрана своего устройства, что значительно ускоряет рабочий процесс и повышает точность подбора цветов.

Пример:

// В фоторедакторе быстрый захват цвета с изображения
func setupColorPickerForPhotoEditing() {
let picker = UIColorPickerViewController()
picker.supportsEyedropper = true
picker.maximumLinearExposure = 1.5
present(picker, animated: true)
}

// В дизайнерском инструменте точный подбор цветов
func createDesignColorWell() -> UIColorWell {
let well = UIColorWell()
well.supportsEyedropper = true
well.maximumLinearExposure = 1.2
return well
}



Практическая значимость для разработчиков:

Эти обновления демонстрируют тенденцию к унификации инструментов выбора цвета между платформами. Теперь UIKit предлагает функциональность, сравнимую с современными веб-решениями и нативными инструментами других операционных систем.

Для разработчиков это означает сокращение необходимости в создании кастомных решений для работы с цветом. Стандартные компоненты теперь покрывают большинство сценариев использования, включая профессиональные задачи, связанные с точным подбором и настройкой цветов.


🔗 Ссылка на подробную статью


💡 Вывод:

Новые возможности UIColorPickerViewController и UIColorWell в iOS 26 значительно расширяют инструментарий разработчика для работы с цветом. Поддержка HDR-цветов через maximumLinearExposure и официальный доступ к инструменту «пипетка» через supportsEyedropper превращают стандартные компоненты в профессиональные решения для современных приложений.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍169🔥42🗿11
This media is not supported in your browser
VIEW IN TELEGRAM
🔢 Обновленное автодополнение кода в Swift.

Сегодня поговорим о важном обновлении в экосистеме Swift, которое существенно улучшит повседневную работу каждого разработчика.

SourceKit-LSP получил серьезные улучшения в системе автодополнения кода. Теперь при написании кода вы видите не просто названия методов, а полноценную документацию с примерами использования и всеми доступными перегрузками.


Что такое SourceKit-LSP:

SourceKit-LSP - это реализация протокола Language Server Protocol (LSP) для языков Swift и C. Если говорить простыми словами, это мост между Swift и различными редакторами кода, который обеспечивает умные возможности в любой среде разработки.


Как это работает:

Представьте: вы начинаете писать метод, и система сразу показывает все возможные варианты его использования с полным описанием параметров. Не нужно переключаться в браузер для поиска документации, вся информация доступна прямо в редакторе. Это работает не только в Xcode, но и в VS Code, Neovim и других популярных средах разработки.


Почему это важно:

Эти изменения экономят время и уменьшают количество ошибок. Особенно ценно это при работе с большими проектами и сложными API, где важно понимать все нюансы использования методов. Разработка становится более интуитивной и эффективной. Теперь разработчики могут выбирать любую удобную среду разработки, не теряя в качестве инструментов.


🔗 Ссылка на подробную статью


💡 Вывод:

Обновления в SourceKit-LSP - это не просто новые фичи, а качественное улучшение процесса разработки. Они делают работу со Swift более комфортной и эффективной, экономя время и уменьшая количество ошибок.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍84211
🔢 Новый Mutex в Swift: современный подход к блокировкам.

Привет! Сегодня разберем новый инструмент для работы с многопоточностью в Swift: фреймворк Synchronization и его основной элемент Mutex. Этот подход предлагает современную альтернативу традиционным блокировкам и особенно полезен в контексте Swift Concurrency.


Что представляет собой новый Mutex:


Mutex из фреймворка Synchronization - это механизм взаимного исключения, обеспечивающий безопасный доступ к разделяемым данным в многопоточной среде. В отличие от более общих концепций блокировок, Mutex следует строгой модели владения: только поток, захвативший блокировку, может ее освободить.

Рассмотрим классический пример с потокобезопасным счетчиком:


final class Counter {
private let count = Mutex<Int>(0)

var currentCount: Int {
count.withLock { $0 }
}

func increment() {
count.withLock { $0 += 1 }
}

func decrement() throws {
try count.withLock {
guard $0 > 0 else { throw Error.reachedZero }
$0 -= 1
}
}
}


Ключевой метод withLock обеспечивает атомарный доступ к защищаемым данным, автоматически управляя блокировкой.


Интеграция с Swift Concurrency:


Особенность нового Mutex: безусловное соответствие протоколу Sendable, что позволяет безопасно использовать его в асинхронном коде. Это решает проблему работы с не Sendable типами в конкурентных контекстах:


final class PathStorage: Sendable {
let path = Mutex<NSBezierPath>(NSBezierPath())

func addPoint(_ point: CGPoint) {
path.withLock { path in
path.move(to: point)
}
}
}



Сравнение с акторами:


Возникает закономерный вопрос: зачем использовать Mutex, если существуют акторы? Ответ лежит в специфике задач:

🔵Акторы идеальны для логической изоляции состояния в асинхронных сценариях.
🔵Mutex эффективен когда требуется синхронный доступ без накладных расходов.
🔵Mutex незаменим при работе с legacy-кодом и API, не поддерживающими Swift Concurrency.


Важные преимущества:

Новый подход предлагает несколько значимых улучшений:

🔵Безопасность типов: Generic-параметризация обеспечивает строгую типизацию.
🔵Интеграция с ошибками: поддержка throwing-операций в блокировках.
🔵Производительность: минимальные накладные расходы по сравнению с традиционными решениями.
🔵Совместимость: беспроблемная работа в синхронных и асинхронных контекстах.


🔗 Ссылка на подробную статью


💡 Вывод:

Synchronization framework и Mutex представляют собой сбалансированное решение для управления многопоточностью в Swift. Они заполняют важный пробел между традиционными блокировками и современными акторами, предлагая инструмент, который одновременно мощный, типобезопасный и эффективный.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍11🔥521👀1
Добро пожаловать в мир Swift от Дена!

Хочешь быть в курсе самых свежих новостей, полезных советов и уникального контента? Тогда наш канал — именно то, что тебе нужно!

Что ты найдёшь в нашем канале:

Полезные статьи и новости из мира технологий и IT.
Уникальные видеоуроки и гайды по программированию.
Обсуждения актуальных тем с нашими подписчиками.
Развлекательный контент, который поможет расслабиться и отдохнуть!

Присоединись к нашему дружному сообществу и будь на шаг впереди! Подписывайся на Swift от Дена и открывай новые горизонты вместе с нами!

Не упустите шанс стать частью нашей команды!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🗿4🔥2👀1
👨‍💻 Мини-приложения в App Store: революция монетизации.

Всем привет! На сайте Apple Developer появился пост о новом API для приложений, которое предлагает расширенные возможности управления встроенными покупками. Речь идет о партнерской программе для мини-приложений в App Store - шаге, который открывает новые возможности для разработчиков крупных платформ.


Суть программы и основные требования:

Apple официально анонсировала программу для мини-приложений: встроенных компонентов, созданных на HTML5, JavaScript и других одобренных языках. Ключевое условие: эти мини-приложения не должны контролироваться разработчиком основного приложения, что предполагает создание открытых экосистем.

Для участия необходимо соответствие нескольким требованиям:

🔵Интеграция Advanced Commerce API для управления покупками.
🔵Использование Declared Age Rating API для возрастной классификации контента.
🔵Обязательное применение встроенных покупок Apple.
🔵Отправка Consumption Information через App Store Server API.


Преимущества для разработчиков:

Основной бенефит программы: сниженная до 15% комиссия за встроенные покупки в мини-приложениях. Это существенно ниже стандартных 30% и создает экономические стимулы для развития платформенных решений.

Программа открывает возможности для:

🔵Создания маркетплейсов мини-приложений.
🔵Развития игровых платформ с пользовательским контентом.
🔵Построения экосистем с сторонними разработчиками.
🔵Легализации существующих моделей с мини-играми и ботами.


Бизнес-перспективы:

Пример Tencent с WeChat демонстрирует потенциал таких экосистем. Программа Apple позволяет легализовать подобные модели в iOS-экосистеме, создавая новые монетизационные каналы. Это может стимулировать появление суперапов - приложений-платформ с множеством встроенных сервисов.


Технические аспекты реализации:

Разработчикам необходимо предусмотреть:

🔵Механизмы изоляции мини-приложений.
🔵Системы модерации контента.
🔵Инфраструктуру для распространения и обновления.
🔵Интеграцию с Apple's Commerce API.


🔗 Подробнее здесь


💡 Вывод:

Партнерская программа Apple для мини-приложений представляет собой стратегический шаг в развитии iOS-экосистемы. Она открывает возможности для создания платформенных решений и новых моделей монетизации, но требует тщательной технической реализации и соблюдения строгих правил. Для крупных разработчиков это шанс построить комплексные экосистемы, в то время как небольшие студии могут найти свою нишу в создании контента для таких платформ.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍9👀6😁21
🔢 Как сделать всю область View кликабельной в SwiftUI.

Сталкивались с ситуацией, когда в SwiftUI кнопка или любая другая View выглядит кликабельной, но не реагирует на нажатия? Это частая проблема, и решение проще, чем кажется.


В чем проблема:

SwiftUI по умолчанию определяет область нажатия только по видимому контенту. Если у вас:

🔵Прозрачные элементы.
🔵View с отступами.
🔵Кастомные фигуры без заливки.
🔵Текст без фона.

То интерактивная область может быть меньше, чем сама View.


Простое решение:

Добавьте модификатор .contentShape() чтобы явно задать область нажатия:

// Было: не работает
Rectangle()
.stroke(Color.blue, lineWidth: 2)
.frame(width: 100, height: 50)
.onTapGesture {
print("Тап!")
}

// Стало: работает
Rectangle()
.stroke(Color.blue, lineWidth: 2)
.frame(width: 100, height: 50)
.contentShape(Rectangle())
.onTapGesture {
print("Тап!")
}



Как это работает:

Модификатор .contentShape() явно задает область, в которой должны распознаваться жесты, независимо от визуального представления. Модификатор принимает несколько вариантов значений:

.contentShape(Rectangle())  // Прямоугольная область
.contentShape(Circle()) // Круглая область
.contentShape(Capsule()) // Капсульная область

// Разные стили для разных случаев
.contentShape(Rectangle(), style: FillStyle())


Параметры FillStyle:

🔵eoFill: Bool - использование правила чет-нечет для сложных фигур.
🔵antialiased: Bool - сглаживание границ.


Пример:


VStack {
Text("Первый элемент")
Text("Второй элемент")
}
.contentShape(Rectangle()) // Общая кликабельная область для всего стека
.onTapGesture {
print("Тап по любой части VStack")
}

Path { path in
path.addRect(CGRect(x: 0, y: 0, width: 100, height: 100))
path.addRect(CGRect(x: 25, y: 25, width: 50, height: 50))
}
.stroke(Color.blue, lineWidth: 2)
.contentShape(
Rectangle(),
style: FillStyle(eoFill: true) // Только внешний прямоугольник кликабелен
)
.onTapGesture {
print("Тап по внешней области")
}


💡 Вывод:

Модификатор contentShape() - это надежное решение проблем с интерактивностью в SwiftUI. Он позволяет точно контролировать, какая область View должна реагировать на жесты, что особенно важно при работе с кастомными фигурами и сложными layout.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍1042🙏1👀1
Forwarded from Кот Денисова
👨‍💻 Deep Coding: осознанная разработка в эпоху искусственного интеллекта.

Всем привет! Пока все увлекаются быстрым «вайбкодингом» с ИИ, появилось противоположное движение: Deep Coding. Это подход, где разработчик сохраняет полный контроль над архитектурой и качеством кода.


В чем суть Deep Coding?

Если «вайбкодинг» - это потоковое генерирование кода с доверием ИИ, то Deep Coding - это осознанное проектирование, где ИИ выступает лишь помощником в реализации деталей.


Как это работает:

Этап 1: архитектурное проектирование.

Прежде чем просить ИИ написать код, вы самостоятельно проектируете каркас будущей системы. Это как архитектор, который сначала создает чертежи здания, а только потом строители начинают работу.

Что конкретно делаете сами:

🔹Определяете границы компонентов: что за что отвечает.
🔹Продумываете взаимодействие между модулями: как они будут общаться.
🔹Проектируете интерфейсы: что каждый компонент должен уметь делать.
🔹Определяете данные: какие структуры информации будут передаваться.
🔹Продумываете ошибки: что может пойти не так и как с этим справляться.

Этап 2: контроль реализации.

Вы используете ИИ для написания конкретных методов, но проверяете каждую строчку кода:

🔹Понимаете логику.
🔹Контролируете качество.
🔹Сохраняете архитектурную целостность.


Преимущества Deep Coding:

🔹Контроль качества: вы понимаете каждый участок кода.
🔹Масштабируемость: продуманная архитектура легче развивается.
🔹Снижение долга: меньше скрытых багов и архитектурных ошибок.
🔹Профессиональный рост: вы продолжаете развивать архитектурные навыки.


Почему это важно именно сейчас:

Рынок начинает ценить не скорость написания кода, а способность создавать поддерживаемые и масштабируемые системы. Junior может сгенерировать код, но только Senior способен спроектировать архитектуру.


💡 Вывод:

Deep Coding - это не отказ от современных инструментов, а разумное их использование. Сохраняйте архитектурное мышление, контролируйте качество кода, и пусть ИИ будет вашим помощником, а не заменой профессиональным навыкам.


➡️ Кот Денисова
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1811🔥5👀221
💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни!

Чтобы принять участие, нужно:
🔹Подписаться на канал.
🔹Нажать кнопку «Участвую!».
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍6🔥4🙏11
Мобильный трудоголик pinned «💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни! Чтобы принять участие, нужно: 🔹Подписаться на канал. 🔹Нажать кнопку «Участвую!».»
🔢 Эффективная работа с данными в Swift: Sequence и Collection.

Привет! Сегодня поговорим об архитектурных основах Swift, которые формируют фундамент работы с данными в наших приложениях. Речь пойдет о протоколах Sequence и Collection, тех строительных блоках, которые мы используем ежедневно, но чьи глубинные механизмы часто остаются за пределами нашего внимания.

В современной Swift-разработке понимание этих протоколов перестает быть опциональным знанием. Сложность приложений растет, требования к производительности ужесточаются, и умение выбирать правильные абстракции для работы с данными становится критически важным навыком.


Sequence:

Sequence представляет собой базовую концепцию последовательности элементов. Его философия проста: объект должен уметь предоставлять элементы один за другим, без обязательств по сохранению состояния или возможности повторного прохода.

Когда мы говорим о Sequence, мы имеем в виду контракт: «я могу дать вам итератор, который будет возвращать элементы до тех пор, пока они не закончатся». Именно эта простота делает Sequence идеальным для:

🔵Работы с потоками данных в реальном времени.
🔵Ленивых вычислений.
🔵Генераторов последовательностей.
🔵Обработки данных, которые доступны только для однократного чтения.


Collection:

Collection - это эволюция Sequence, добавляющая строгие гарантии и дополнительные возможности. Если Sequence - это поток, то Collection - это структурированное хранилище. Ключевые преимущества Collection включают:

🔵Гарантированную возможность многократной итерации.
🔵Стабильность порядка элементов (где это применимо).
🔵Эффективный доступ по индексам.
🔵Предсказуемую производительность операций.


Механика итерации:

То, что выглядит как простой синтаксический сахар:


for element in collection {
// обработка элемента
}


На самом деле преобразуется в полноценный механизм итерации:


var iterator = collection.makeIterator()
while let element = iterator.next() {
// обработка элемента
}


Такой подход обеспечивает несколько важных преимуществ:

🔵Безопасность: итератор работает с моментальным снимком состояния, защищая от изменений коллекции во время обхода.
🔵Гибкость: разные типы могут предоставлять специализированные итераторы.
🔵Производительность: компилятор может оптимизировать итерацию на основе знаний о конкретном типе.


Асинхронная революция: AsyncSequence

С приходом Swift Concurrency модель итерации получила развитие в виде AsyncSequence. Этот протокол расширяет знакомые концепции для работы с асинхронными потоками данных:


for try await event in eventStream {
await processEvent(event)
}


AsyncSequence становится особенно важен в контексте:

🔵Сетевых операций.
🔵Обработки реального времени.
🔵Работы с внешними источниками данных.
🔵Реактивного программирования.


Рекомендации:

Когда выбирать Sequence:

🔵Данные генерируются на лету.
🔵Требуется ленивая загрузка.
🔵Работа с потоками в реальном времени.
🔵Необходим единоразовый доступ к данным.

Когда выбирать Collection:

🔵Необходим многократный доступ к данным.
🔵Важна стабильность порядка.
🔵Требуется эффективный доступ по индексу.
🔵Данные фиксированы или изменяются редко.


Производительность:

Глубокое понимание иерархии протоколов позволяет писать более эффективный код. Компилятор Swift использует знания о соответствии типов этим протоколам для применения агрессивных оптимизаций:

🔵Специализация generic-функций.
🔵Предварительное выделение памяти.
🔵Оптимизация доступа по индексу.
🔵Устранение избыточных проверок.


🔗 Ссылка на подробную статью


💡 Вывод:

Sequence и Collection - это фундаментальные подходы к работе с данными в Swift. Понимание их различий позволяет выбирать оптимальные решения для конкретных задач, предвидеть проблемы производительности и создавать эффективные кастомные реализации.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
17🔥11👍6211🙏1
🔢 Владение данными в Swift: Как ~Copyable делает код безопаснее.

Всем привет! Сегодня поговорим о протоколе ~Copyable. Данный протокол позволяет запретить неявное копирование структур, что особенно полезно при работе с ресурсами вроде файлов или сетевых соединений.


Проблема, которую решает ~Copyable:

Представьте, что у вас есть структура для работы с файлом:


struct FileHandler: ~Copyable {
private var fileDescriptor: Int32

init(path: String) {
fileDescriptor = open(path, O_RDWR)
}

consuming func close() {
close(fileDescriptor)
}
}

// Временный доступ для чтения
func readFromFile(_ handler: borrowing FileHandler) {
let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 1024, alignment: 1)
defer { buffer.deallocate() }

let bytesRead = read(handler.fileDescriptor, buffer.baseAddress, 1024)
if bytesRead > 0 {
print("Прочитано \(bytesRead) байт")
}
}

// Передача владения
func takeOwnership(of handler: consuming FileHandler) {
print("Закрываем файл с дескриптором \(handler.fileDescriptor)")
handler.close()
}

// Изменение без передачи владения
func modifyFile(_ handler: inout FileHandler) {
let data = "Новые данные".data(using: .utf8)!
_ = data.withUnsafeBytes { buffer in
write(handler.fileDescriptor, buffer.baseAddress, buffer.count)
}
print("Данные записаны в файл")
}

let file = FileHandler(path: "data.txt")
readFromFile(file) // borrowing: file остается доступен
modifyFile(&file) // inout: изменяем, но владение не передается
takeOwnership(of: file) // consuming: передача владения, file больше не доступен
// file.close() // Ошибка компиляции! file уже недоступен


Без ~Copyable можно случайно создать копию структуры и получить две независимые переменные, работающие с одним файловым дескриптором. Это может привести к:

🔵Попытке двойного закрытия файла.
🔵Конфликтующим операциям чтения/записи.
🔵Трудноотлавливаемым багам.


Как это работает:

После добавления ~Copyable компилятор начинает следить за перемещением экземпляров структуры. Теперь нужно явно указывать:

🔵borrow: для временного доступа без передачи владения.
🔵consume: для полной передачи владения.
🔵inout: для временного изменения.


Когда это может быть полезно:

~Copyable особенно пригодится при:

🔵Работе с файлами, сокетами, внешними ресурсами.
🔵Использовании низкоуровневых API через указатели.
🔵Создании библиотек, где важно контролировать жизненный цикл объектов.
🔵Разработке высокопроизводительного кода.


🔗 Ссылка на подробную статью


💡 Вывод:

~Copyable - это не просто очередная фича языка, а важный шаг к более безопасному и предсказуемому коду. Хотя подход требует некоторого переосмысления работы со структурами, результат стоит того: многие потенциальные ошибки переносятся из времени выполнения в время компиляции, что экономит часы отладки.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍12🔥52🙏1👀1