Обнаружилась серьезная проблема в 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
Всем привет! Сегодня разберем механизм 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 успешно справляется самостоятельно.
Критические сценарии применения:
Подробные статьи:
AutoreleasePool остается специализированным инструментом для оптимизации пикового потребления памяти. Его разумное применение особенно важно в высоконагруженных приложениях, где контроль за памятью напрямую влияет на производительность и стабильность приложения.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
С выходом 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
👍16 9🔥4❤2🗿1 1
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня поговорим о важном обновлении в экосистеме 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👍8 4 2❤1 1
Привет! Сегодня разберем новый инструмент для работы с многопоточностью в 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, если существуют акторы? Ответ лежит в специфике задач:
Важные преимущества:
Новый подход предлагает несколько значимых улучшений:
Synchronization framework и Mutex представляют собой сбалансированное решение для управления многопоточностью в Swift. Они заполняют важный пробел между традиционными блокировками и современными акторами, предлагая инструмент, который одновременно мощный, типобезопасный и эффективный.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Хочешь быть в курсе самых свежих новостей, полезных советов и уникального контента? Тогда наш канал — именно то, что тебе нужно!
Что ты найдёшь в нашем канале:
Присоединись к нашему дружному сообществу и будь на шаг впереди! Подписывайся на Swift от Дена и открывай новые горизонты вместе с нами!
Не упустите шанс стать частью нашей команды!
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Swift от Дена
IOS разработчик. Swift/SwiftUI
GitHub - https://github.com/Den1Doc
App Store - https://apps.apple.com/ru/app/%D0%BC%D0%BE%D1%8F-%D1%82%D0%B0%D1%87%D0%BA%D0%B0-%D1%82%D1%80%D0%B5%D0%BA%D0%B5%D1%80-%D0%B0%D0%B2%D1%82%D0%BE/id6739165836
GitHub - https://github.com/Den1Doc
App Store - https://apps.apple.com/ru/app/%D0%BC%D0%BE%D1%8F-%D1%82%D0%B0%D1%87%D0%BA%D0%B0-%D1%82%D1%80%D0%B5%D0%BA%D0%B5%D1%80-%D0%B0%D0%B2%D1%82%D0%BE/id6739165836
👍9🗿4🔥2👀1
Всем привет! На сайте Apple Developer появился пост о новом API для приложений, которое предлагает расширенные возможности управления встроенными покупками. Речь идет о партнерской программе для мини-приложений в App Store - шаге, который открывает новые возможности для разработчиков крупных платформ.
Суть программы и основные требования:
Apple официально анонсировала программу для мини-приложений: встроенных компонентов, созданных на HTML5, JavaScript и других одобренных языках. Ключевое условие: эти мини-приложения не должны контролироваться разработчиком основного приложения, что предполагает создание открытых экосистем.
Для участия необходимо соответствие нескольким требованиям:
Преимущества для разработчиков:
Основной бенефит программы: сниженная до 15% комиссия за встроенные покупки в мини-приложениях. Это существенно ниже стандартных 30% и создает экономические стимулы для развития платформенных решений.
Программа открывает возможности для:
Бизнес-перспективы:
Пример Tencent с WeChat демонстрирует потенциал таких экосистем. Программа Apple позволяет легализовать подобные модели в iOS-экосистеме, создавая новые монетизационные каналы. Это может стимулировать появление суперапов - приложений-платформ с множеством встроенных сервисов.
Технические аспекты реализации:
Разработчикам необходимо предусмотреть:
Партнерская программа Apple для мини-приложений представляет собой стратегический шаг в развитии iOS-экосистемы. Она открывает возможности для создания платформенных решений и новых моделей монетизации, но требует тщательной технической реализации и соблюдения строгих правил. Для крупных разработчиков это шанс построить комплексные экосистемы, в то время как небольшие студии могут найти свою нишу в создании контента для таких платформ.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍9👀6😁2 1
Сталкивались с ситуацией, когда в SwiftUI кнопка или любая другая View выглядит кликабельной, но не реагирует на нажатия? Это частая проблема, и решение проще, чем кажется.
В чем проблема:
SwiftUI по умолчанию определяет область нажатия только по видимому контенту. Если у вас:
То интерактивная область может быть меньше, чем сама 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:
Пример:
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
Forwarded from Кот Денисова
Всем привет! Пока все увлекаются быстрым «вайбкодингом» с ИИ, появилось противоположное движение: 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👍18❤11🔥5👀2 2✍1
💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни!
Чтобы принять участие, нужно:
🔹 Подписаться на канал.
🔹 Нажать кнопку «Участвую!».
Чтобы принять участие, нужно:
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Мобильный трудоголик
🍏 🏋️ Мое приложение для отказа от вредных привычек.
Во второй половине 2023 года, после множества доработок чужих приложений на фрилансе, связанных с улучшением здоровья и качества жизни, у меня появилась идея создать собственный счетчик отказа от вредных…
Во второй половине 2023 года, после множества доработок чужих приложений на фрилансе, связанных с улучшением здоровья и качества жизни, у меня появилась идея создать собственный счетчик отказа от вредных…
❤9👍6🔥4🙏1 1
Мобильный трудоголик pinned «💚 Дарим три подписки на полгода в приложении «Счетчик дней: вредные привычки» - помощника в борьбе с вредными привычками для поддержания здорового образа жизни! Чтобы принять участие, нужно: 🔹 Подписаться на канал. 🔹 Нажать кнопку «Участвую!».»
Привет! Сегодня поговорим об архитектурных основах 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 использует знания о соответствии типов этим протоколам для применения агрессивных оптимизаций:
Sequence и Collection - это фундаментальные подходы к работе с данными в Swift. Понимание их различий позволяет выбирать оптимальные решения для конкретных задач, предвидеть проблемы производительности и создавать эффективные кастомные реализации.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет! Сегодня поговорим о протоколе ~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 компилятор начинает следить за перемещением экземпляров структуры. Теперь нужно явно указывать:
Когда это может быть полезно:
~Copyable особенно пригодится при:
~Copyable - это не просто очередная фича языка, а важный шаг к более безопасному и предсказуемому коду. Хотя подход требует некоторого переосмысления работы со структурами, результат стоит того: многие потенциальные ошибки переносятся из времени выполнения в время компиляции, что экономит часы отладки.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM