Мобильный трудоголик
1.37K subscribers
61 photos
9 videos
266 links
👨‍💻 Пишу простым языком об iOS разработке на Swift и мобильной разработке в целом.
🔹 Вошел в IT задолго до того как это стало мейнстримом.
---
‍Обо мне: https://t.me/hardworkerIT/3
Чат: @hardworkerChatIT
Канал про разработку и жизнь в ИТ: @itDenisov
Download Telegram
👨‍💻 Мобильная разработка умирает?

Последнее время всё чаще слышу этот вопрос. Давайте разберёмся: что на самом деле происходит с мобилкой?


Симптомы «кризиса».

🔸 Найм замер – компании берут только сеньоров, джунам пробиться почти нереально.
🔸 Технологический застой – ничего революционного (после SwiftUI, async/await, Flutter, KMM, Jetpack Compose).
🔸 Смартфоны перестали удивлять – Apple и Samsung 5 лет выпускают «одно и то же».
🔸 Конференции скукожились – где тот размах Mobile World Congress или Mobius?


⚠️ Что на самом деле?

Мобильная разработка не умирает – она перестала быть хайповой.
🔹 Mobile-First умер? Да, теперь все говорят про AI-First.
🔹 Значит ли это, что мобилки больше нет? Нет – просто она стала стандартной индустрией, как веб-разработка.


🤔 Что будет дальше?

🔸 Сильные разработчики останутся: спрос на опытных iOS/Android разрабов никуда не денется.
🔸 Новичкам будет сложнее: входной барьер вырос в разы.
🔸 Фокус сместится на интеграцию: AI, AR, кроссплатформа (Flutter, KMM).


💡 Вывод:

Мобильная разработка больше не «золотая лихорадка», но остаётся стабильной областью для профессионалов.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👀16🫡7🗿41🤔1🤯1
🔢 Эффективное управление памятью в iOS: как снизить потребление и избежать проблем.

Работа с памятью — одна из самых сложных тем в разработке мобильных приложений. Если не уделять этому внимание, приложение начнёт тормозить, вылетать или даже «съедать» всю память устройства.

Существует два подхода к управлению памятью:
🔹 Реактивный: решаем проблемы по мере их появления. Подходит для небольших проектов с жёсткими дедлайнами, но может привести к серьёзному техдолгу.
🔹 Проактивный: заранее оптимизируем код, используем правильные инструменты и следим за потреблением памяти. Это сложнее, но экономит время в долгосрочной перспективе.


🤔 Где искать утечки и как их избежать?


1️⃣ Оптимизация изображений.

Загрузка больших изображений — частая причина утечек. Что делать?

🔹 Используйте Image I/O для создания миниатюр.
🔹 Загружайте картинки лениво (например, через AsyncImage или Kingfisher).
🔹 Храните ассеты в каталогах — они автоматически оптимизируются под разные устройства.


2️⃣ Работа с Core Data.

Core Data хранит изменения в памяти до сохранения (save()). Если откладывать сохранение слишком долго — память заполнится. Если сохранять слишком часто — нагрузка на диск возрастёт. Нужен баланс.


3️⃣ Используйте NSPurgeableData.

Этот класс позволяет системе автоматически освобождать память при нехватке. Просто оберните в него данные и вызывайте beginContentAccess() при необходимости.


4️⃣ Ленивая загрузка (LazyVStack, lazy var).

🔹 В SwiftUI используйте LazyVStack и LazyHStack, чтобы загружать элементы только при появлении на экране.
🔹 В коде применяйте lazy var для редко используемых свойств (например, кэшированных изображений).


5️⃣ Отдавайте предпочтение value-типам (struct, enum).

Они проще в управлении памятью, так как не создают retain-циклов и освобождаются сразу после выхода из области видимости.


6️⃣ Правильное кэширование.

🔹 Используйте NSCache — он автоматически очищается при нехватке памяти.
🔹 Избегайте сильных ссылок на большие объекты.
🔹 Реализуйте свою стратегию очистки (например, по времени или частоте использования).


7️⃣ Удаляйте неиспользуемые объекты.

Если данные больше не нужны (например, пользователь ушёл в другой раздел приложения), освобождайте память: останавливайте таймеры, отменяйте запросы, выгружайте тяжелые ресурсы.


8️⃣ Боритесь с утечками.

🔹 Используйте Memory Graph Debugger в Xcode.
🔹 Проверяйте retain-циклы в замыканиях ([weak self]), делегатах и связях View-ViewController.
🔹 Регулярно запускайте Instruments (Leaks) во время тестирования.


💡 Вывод:

Управление памятью — это баланс между производительностью и потреблением ресурсов. Чем раньше вы начнёте следить за этим, тем стабильнее будет ваше приложение.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
118👍4🙏3🔥21
🔢 Преобразование речи в текст в iOS приложении.

Компания Apple представила новый API SpeechAnalyzer — мощный инструмент для работы с аудио в iOS 26. Рассказываю, как интегрировать его в ваше приложение для преобразования речи в текст.


⚠️ Ключевые компоненты:

AudioManager:
Управляет доступом к микрофону и аудиосессией. Обрабатывает разрешения и потоковую передачу аудиобуферов в реальном времени.

BufferConverter:
Преобразует аудиобуферы между форматами — критично для совместимости с SpeechAnalyzer.

TranscriptionManager:
Координирует весь процесс: запрос разрешений, запуск транскрипции и обработку результатов.


♣️ Особенности реализации:


// Пример обработки аудиобуфера
func processAudioBuffer(_ buffer: AVAudioPCMBuffer) throws {
guard let inputBuilder, let analyzerFormat else { return }
let converted = try converter.convertBuffer(buffer, to: analyzerFormat)
inputBuilder.yield(AnalyzerInput(buffer: converted))
}



Важные нюансы:

🔸 Требуются разрешения Microphone и Speech Recognition.
🔸 Оптимизирован для длинных аудиозаписей.
🔸 Лучше работает с голосом на расстоянии.


Практическое применение:

🔹 Голосовые заметки.
🔹 Субтитры в реальном времени.
🔹 Голосовые сообщения в мессенджерах.
🔹 Голосовое управление приложением.
🔹 Анализ аудиоконтента.


💡 Вывод:

SpeechAnalyzer открывает новые возможности для голосовых интерфейсов. Хотя API ещё сыроват, его уже можно использовать в проектах — главное не забывать про обработку ошибок и проверку разрешений.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥164👍31👏1
🔢 Approachable Concurrency в Swift: новая эра многозадачности.

В Xcode 26 появился революционный подход к работе с многозадачностью: Approachable Concurrency. Это не просто одно изменение, а целый набор фич, которые делают конкурентный код проще и предсказуемее.


⚠️ Что входит в Approachable Concurrency:

🔸 nonisolated(nonsending) By Default: неизолированные async-функции теперь выполняются на исполнителе вызывающего актора.
🔸 Infer Sendable for Methods: автоматическое определение Sendable для методов и key-path.
🔸 Infer Isolated Conformances: автоматическая изоляция протокольных конформянсов под актор типа.
🔸 Глобальная изоляция типов: умное определение безопасного использования неизолированных свойств.
🔸 Отключение неявной изоляции: больше не нужно бороться с неожиданной изоляцией через property wrappers.


👔 Как включить.

В Xcode:

🔹 Идем в Build Settings, затем ищем «Approachable Concurrency».
🔹 Устанавливаем значение: Yes.

В Swift Package:

swift 
// swift-tools-version: 6.2
.target(
name: "MyFeature",
swiftSettings: [
.defaultIsolation(MainActor.self),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("InferIsolatedConformances")
]
)



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

🔸 Меньше неожиданностей: компилятор стал умнее определять реальные data races.
🔸 Более понятные ошибки: никаких загадочных сообщений о проблемах изоляции.
🔸 Естественный прогресс: начинаете с main actor, переходите на фоновые потоки только когда нужно.


Особенности работы:

🔹 В Swift 6 некоторые фичи включены по умолчанию.
🔹 Для Swift 5 нужно явное включение через настройки.
🔹 Пока есть некоторые баги (например, с CodingKey), но они исправляются.


💡 Вывод:

Approachable Concurrency — это большой шаг к тому, чтобы многозадачность в Swift стала более понятной и удобной для всех разработчиков.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1684🔥2🙏1👀1🫡1
👨‍💻 Отказ это не конец, а повод сменить тактику.

Получили шаблонное письмо с отказом? Первая реакция — разочарование и самокритика. Но в 80% случаев причина не в вас лично.


⚠️ Ключевые, не очевидные причины отказов:

🔸 Внутренний трансфер: вакансию создали под конкретного сотрудника.
🔸 Скрытый фриз: нанимают только senior-специалистов или приостановили найм.
🔸 Изменился портрет кандидата: ищут человека с опытом в другой индустрии.
🔸 Психологическая несовместимость: руководитель ощутил «не тот vibe».


Что скрывают рекрутеры:

🔸 Другой кандидат согласился на меньшую зарплату.
🔸 Вы были «запасным вариантом».
🔸 HR перегружен и не провел полноценный скрининг.
🔸 Вакансию закрыли из-за реорганизации.


Тактика действий после отказа:

🔹 Запросите конструктивный фидбек, спросите: «Какие конкретно навыки мне стоит прокачать?».
🔹 Сохраните контакт: добавьте HR в контакты LinkedIn или сохраните контакт в Telegram.
🔹 Предложите остаться в кадровом резерве: 37% компаний возвращаются к отказавшим кандидатам.
🔹 Проанализируйте этапы: если отказ после скрининга — работайте над резюме, после технического собеседования — над технические-скиллы.

Важный момент: создайте таблицу для отслеживания откликов с колонками:
🔹 Компания
🔹 Этап отказа
🔹 Полученный фидбек
🔹 Дата повторного контакта

Через 3 месяца напишите обновление: «Прошёл курс по X, добавил в портфолио Y. Хотел бы попробоваться на вашу позицию».

Помните:
🔸 Средний специалист получает 7 отказов перед оффером.
🔸 20% предложений поступают от компаний, которые ранее отказывали.
🔸 Каждый отказ это тренировка переговорных навыков.


💡 Вывод:

Не сжигайте мосты, мир IT тесен. Вежливость и профессиональное поведение после отказа часто вознаграждаются.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1985🔥2👀1🫡1
🔢 SwiftUI: защита конфиденциальных данных при скриншоте или записи экрана.

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

Основная идея заключается в использовании Secure TextField, который iOS автоматически размывает при попытке захвата экрана. Вот как это можно реализовать:


1️⃣ Создаем обертку SecureContentWrapper для скрытия контента:


struct SecureContentWrapper<Content: View>: UIViewRepresentable {
let content: Content

func makeUIView(context: Context) -> UIView {
let hostingController = UIHostingController(rootView: content)
let secureField = UITextField()
secureField.isSecureTextEntry = true
secureField.addSubview(hostingController.view)
return secureField
}

func updateUIView(_ uiView: UIView, context: Context) {}
}



2️⃣ Для удобства использования создаем модификатор:


struct ContentProtector: ViewModifier {
@State private var contentSize: CGSize = .zero

func body(content: Content) -> some View {
SecureContentWrapper(content: content)
.frame(width: contentSize.width, height: contentSize.height)
.background(
GeometryReader { proxy in
Color.clear
.preference(key: ContentSizePreference.self, value: proxy.size)
}
)
.onPreferenceChange(ContentSizePreference.self) { size in
self.contentSize = size
}
}
}

struct ContentSizePreference: PreferenceKey {
static var defaultValue: CGSize = .zero

static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}



3️⃣ Добавляем расширение для View:


extension View {
func protectContent() -> some View {
self.modifier(ContentProtector())
}
}



♣️ Пример использования:


struct PrivateDataView: View {
var body: some View {
VStack {
Text("Номер карты: 1234 **** **** 5678")
.font(.title)

Text("Срок действия: 12/34")

Text("CVV: 123")
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(12)
.protectContent()
}
}



⚠️ Важные моменты:

🔸 Защита работает только при активном захвате экрана.
🔸 Не предотвращает фотографирование экрана другим устройством.
🔸 Для максимальной безопасности комбинируйте с другими методами.


💡 Вывод:

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

Главное преимущество подхода: его простота и отсутствие необходимости в сложных вычислениях или дополнительных разрешениях.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2285🔥2🙏2🤝1🫡1
This media is not supported in the widget
VIEW IN TELEGRAM
17👍74🔥2🙏2
Добро пожаловать в мир Swift от Дена!

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

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

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

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

Не упустите шанс стать частью нашей команды!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12👀6🔥3😁3🗿3🤔1
🔨 Xcode 26 ускоряет сборки: появилось кеширование компиляции!

В Xcode 26 RC добавили ручное включение кеширования компиляции и это может серьезно ускорить вашу разработку.


⚠️ Как это работает?

Теперь можно закешировать результаты компиляции Swift и C-подобных языков. При повторной сборке тех же файлов Xcode будет брать их из кеша, а не пересобирать с нуля.


🔗 Xcode 26 RC Release Notes


👨‍💻 Мое мнение:

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


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
23👍1465🔥1👏1
👨‍💻 Эффективный рост в IT: как развиваться быстрее других.

Если вы до сих пор считаете, что карьерный рост в IT ограничивается сменой компании или добавлением нового фреймворка в резюме, то приготовьтесь к жесткой реальности.

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


1️⃣ Стратегия роста: осознанный шаг, а не прыжок в пустоту.

Смена специализации или поиск новой работы это не «попробую, что предложат». Это точечный расчет.

Пример:
Вы backend-разработчик и хотите уйти в Data Engineering. Ваш план:

🔹 Не бросать текущую работу в порыве «ненавижу этот код».
🔹 Составить карту навыков: что уже умеете, чего не хватает, какие проекты можно сделать для портфолио.
🔹 Узнать у рекрутеров, на сервисах по поиску работы или в чатах: какие компании ищут таких гибридных специалистов и под какой стек.

Важно: Не учите всё подряд. Сфокусируйтесь на том, что действительно требуется в вакансиях выше уровня или новой специальности.


2️⃣ ИИ ваш партнер в апгрейде, а не угроза.

Да, ИИ пишет код. Но он не может выстроить архитектуру, прочувствовать продукт или понять бизнес-логику. Его сила в скорости рутины. Ваша в экспертизе.

Как использовать ИИ для роста:

🔹 Поручите ему рутинные задачи: генерация тестов, шаблонного-кода, документации.
🔹 Используйте для изучения нового: «Объясни разницу между Grand Central Dispatch и OperationQueues», получите выжимку, углубляйтесь сами.
🔹 Декомпозируйте сложные задачи: «Как перейти от MVC к VIPER?», получите от ИИ план внедрения, проанализируйте предложенную архитектуру, найдите слабые места и адаптируйте под конкретные нужды вашего проекта.


3️⃣ Кризис = время для переговоров.

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

Но есть нюансы:

🔹 Не меняйте работу случайным образом. Изучите стек и боли нового работодателя.
🔹 Готовьтесь к сложным техническим собеседованиям, на них стали глубже спрашивать про архитектуру и принятие решений.
🔹 Используйте нетворкинг: 70% крутых вакансий не публикуются, их занимают по рекомендациям.


4️⃣ Рост это всегда практика, а не сертификаты.

Нельзя вырасти до архитектора, только прочитав книжки. Нужно делать проекты, ошибаться и исправлять последствия.

Ваш план роста:

🔹 Если хотите сменить специализацию, то начните с внутреннего перехода в компании. Так безопаснее.
🔹 Участвуйте в опенсорсе или создайте свой проект на новом стеке. Это лучше любого резюме.
🔹 Просите фидбек у коллег и менторов, без него вы не увидите слепых зон.


5️⃣ Менторство и комьюнити — лифт для карьеры.

Самостоятельно расти можно, но медленно и с ошибками. Окружение ускоряет рост.

Что делать:

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


6️⃣ Фокус на качестве, а не на количестве технологий.

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

Как проверить, туда ли вы растете:

🔹 Сравните свой стек с вакансиями мечты. Уберите лишнее, добавьте недостающее.
🔹 Спросите себя: «Что я сделал за последние 3 месяца, чтобы стать ближе к цели?» Если ответа нет, меняйте тактику.
🔹 Не бойтесь отказываться от проектов или задач, которые не ведут к цели.


💡 Вывод:

2025-2026 год станет временем настоящих профессионалов, а не универсальных специалистов широкого профиля. Успеха добьются те, кто делает ставку на глубокую экспертизу, а не поверхностное знакомство с технологиями. Умение эффективно использовать ИИ для рутинных задач и строить сильное профессиональное сообщество вокруг себя станет ключевым преимуществом.


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

В Swift есть несколько подходов для работы с потоками и асинхронными задачами. Вот ключевые методы:

1️⃣ Grand Central Dispatch (GCD) — DispatchQueue.

Позволяет легко выполнять код в фоне или на главном потоке.

// Фоновый поток
DispatchQueue.global().async {
// Тяжелые вычисления или сетевые запросы
DispatchQueue.main.async {
// Обновляем UI (только в главном потоке!)
}
}


2️⃣ Swift Concurrency (Task, async/await).

Современный способ для асинхронного кода.

Task {
// Асинхронная работа
let result = await networkRequest()

await MainActor.run {
// Обновляем UI (только в главном потоке!)
updateUI(with: result)
}
}

...

@MainActor
private func updateUI(with result: String) {
}


3️⃣ OperationQueue.

Для сложных зависимостей между задачами.

let queue = OperationQueue()
queue.addOperation {
// Фоновая задача
}


⚠️ Важные правила:

🔸 UI-обновления: только в главном потоке (DispatchQueue.main), @MainActor.
🔸 Глобальные очереди (global()): для CPU-интенсивных задач.
🔸 Асинхронность (async): чтобы не блокировать текущий поток.


🤔 Когда что использовать?

🔹 DispatchQueue: для простых фоновых задач.
🔹 Task: для современного асинхронного кода (с async/await).
🔹 OperationQueue: для сложных цепочек операций.


💡 Вывод:

Выбирайте инструмент под задачу, но всегда помните о потокобезопасности!

➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍231052🔥1🤝1
🔢 Что изменилось в поиске на iOS 26: разбор новых возможностей SwiftUI.

Всем привет! Если вы обновляете свое приложение под iOS 26, то обратили внимание на поиск. Apple серьезно переработала не только визуал, но и логику размещения поисковых интерфейсов.

Рассказываю, как это работает теперь, с живыми примерами и кодом.


1️⃣ Поиск в toolbar.

Раньше поиск в NavigationSplitView автоматически размещался в сайдбаре на iPad и вверху экрана на iPhone. Теперь система сама выбирает оптимальное расположение:

// Раньше: поиск всегда в сайдбаре
NavigationSplitView {
List(notes, selection: $selectedNote) { note in
NavigationLink(note.title, value: note)
}
.navigationTitle("Notes")
} detail: {
NoteDetailView(note: selectedNote)
}
.searchable(text: $searchText) // Новый стиль по умолчанию


В iOS 26 тот же код дает совершенно другой результат:

🔹На iPad: поиск в стеклянном контейнере в правом верхнем углу.
🔹На iPhone: поиск внизу экрана (удобно для больших экранов).

Хотите вернуть старое поведение? Укажи явное размещение:

.searchable(text: $searchText, placement: .sidebar)



2️⃣ Поиск в detail view.

Если поиск нужен только в детальном представлении, то модификатор применяется к нему:

NavigationSplitView {
// Список без поиска
} detail: {
NoteDetailView(note: selectedNote)
.searchable(text: $searchText) // Только для детального просмотра
}


Здесь тоже работает новое позиционирование: сверху на iPad, снизу на iPhone.


3️⃣ Поиск в tabBar.

Для приложений с табБаром появился отдельный сценарий. Создаем вкладку с ролью .search:

TabView {
Tab("Library", systemImage: "books.vertical") {
LibraryView()
}

Tab(role: .search) { // Важно: роль search
NavigationStack { // Обязательно в NavigationStack
SearchView()
.navigationTitle("Search")
}
}
}
.searchable(text: $searchText)


В iOS 26 такая вкладка:

🔹 Визуально отделена от других.
🔹 Превращается в поисковое поле при выборе.
🔹 На iPad размещается по центру сверху.


⚠️ Новые toolbar-компоненты.

Самое интересное — кастомизация нижнего toolbar. Добавлены два новых типа контента:

.toolbar {
if #available(iOS 26.0, *) {
DefaultToolbarItem(kind: .search, placement: .bottomBar) // Новый!
ToolbarSpacer(.flexible, placement: .bottomBar) // И этот новый
}

ToolbarItem(placement: .bottomBar) {
NewNoteButton() // Ваша кастомная кнопка
}
}


Так поиск и другие элементы toolbar правильно распределят пространство.


Минимизация поиска.

Если поиск не основная функция, можно свернуть его в кнопку:

// Создаем extension для удобства
extension View {
@ViewBuilder func minimizedSearch() -> some View {
if #available(iOS 26.0, *) {
self.searchToolbarBehavior(.minimize)
} else {
self
}
}
}

// Использование
.searchable(text: $searchText)
.minimizedSearch() // Теперь это кнопка поиска!


Система может применить это поведение автоматически, в зависимости от размера экрана или количества элементов toolbar.


💡 Вывод:

Большинство изменений в поиске iOS 26 работают автоматически, достаточно обновить приложение до новых API. Новый дизайн обеспечивает единый стиль и улучшенный UX, особенно для больших экранов, при этом сохраняя гибкость кастомизации.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25124🔥1🤝11
📱 Вайбкодеры vs Разработчики: почему холивар бесполезен, а ИИ это просто новый инструмент.

Все чаще в интернете возникают споры: одни ребята в восторге от того, как ИИ (тот же Cursor) генерит за них код. Другие, классические разработчики, смотрят на это скептически и даже свысока. Мол, «настоящие программисты так не делают», а вайбкодеры просто копипастят код без понимания. Давайте разбираться.


⚠️ Что такое «вайбкодинг»?

Если коротко, это когда ты не пишешь код вручную, а объясняешь задачу ИИ «человеческими» словами. А он тебе выдает готовый кусок программы. Это как давать задание умному стажеру, который мгновенно его выполняет.

Идею популяризировал Андрей Карпати (экс-Tesla AI). Его подход: «Я вижу что-то, говорю что-то, запускаю, копирую и это в основном работает». Звучит знакомо, правда?


Мой опыт работы с Cursor.

Недавно мне понадобилось собрать прототип мобильного приложения под iOS с базовым экраном профиля, настройками и простой авторизацией. По старинке я бы потратил день только на то, чтобы прописать основные View, настроить навигацию между экранами и организовать простые сетевые запросы. Но с тем же Cursor я получил готовый каркас на SwiftUI буквально за полчаса. Да, потом я ещё правил логику, допиливал интерфейс и адаптировал под свои нужды. Но самое утомительное, создание базовой структуры, верстка стандартных элементов — всё это за меня сделал ИИ.

И это круто не потому, что я «разленился» или забыл, как пишется код. А потому, что вместо часов кропотливой рутины я сразу смог заняться тем, что действительно важно: проектированием пользовательского опыта, анимациями и продумыванием того, как всё будет работать вместе. ИИ взял на себя черную работу, а я сосредоточился на творческой.


👨‍💻 О скептическом отношении опытных разработчиков.

Их скепсис мне понятен. Вот пару аргументов, с которыми я сталкивался:

🔸 «Это код низкого качества». ИИ часто выдает работающее, но неоптимальное или небезопасное решение. Без глубоких знаний это не проверить.
🔸 «Таких джунов не возьмут на работу». CEO одной студии прямо заявил, что не стал бы нанимать человека, который просто копипастит код из ИИ без понимания.

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

Но вот важный нюанс: многие стартапы уже генерируют по 80-90% кода через ИИ. Но делают это как раз технически сильные основатели, которые могли бы написать всё сами, но теперь экономят время.


🤔 Так в чём же суть?

Для меня вайбкодинг это не про лень и не про «халяву». Это про эффективность.

🔹 Это смена роли: из «того, кто печатает код» в «того, кто ставит задачи и проверяет результат».
🔹 Это ускорение: можно за день сделать прототип, на который раньше ушла бы неделя.
🔹 Это обучение: ИИ отлично помогает разобраться в новом языке или фреймворке, давая примеры «здесь и сейчас».

Да, ответственность никуда не делась. Код всё так же нужно тестировать, ревьюить и продумывать архитектуру. ИИ не отменяет need-to-know. Но он автоматизирует рутину.


💡 Вывод:

Спор «вайбкодеры vs разработчики» бесполезен. Настоящий прорыв происходит не на этих баррикадах, а у тех, кто использует ИИ как мощный инструмент для усиления своих возможностей.

Не за горами время, когда ценностью будет не умение быстро писать код, а умение чётко ставить задачи ИИ, проверять и дорабатывать результат. Креатив и архитектурное мышление выйдут на первый план.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21👀9🔥42👏1😁1🤯1
🔢 SwiftUI WebView: работаем с веб-контентом.

На WWDC 2025 компания Apple представила долгожданный нативный WebView для SwiftUI.


⚠️ Базовое использование:

// Инициализация WebPage
@State private var page = WebPage()

// Загрузка контента
WebView(page: page)
.onAppear {
let request = URLRequest(url: URL(string: "https://apple.com")!)
page.load(request)
}



⚙️ Ключевые возможности:


1️⃣ Загрузка локального контента.

let htmlString = "<h1>Локальный контент</h1>"
page.load(html: htmlString, baseURL: Bundle.main.resourceURL)



2️⃣ Отслеживание загрузки.

VStack {
// Индикатор прогресса
if page.isLoading {
ProgressView(value: page.estimatedProgress)
}
}



3️⃣ Кастомные схемы URL.

Регистрация обработчика для собственных URL-схем:

let scheme = URLScheme("myapp")!
var config = WebPage.Configuration()
config.urlSchemeHandlers[scheme] = CustomSchemeHandler()
page = WebPage(configuration: config)



4️⃣ Управление навигацией.

Контроль перехода по ссылкам через NavigationDecider:

class CustomNavigationDecider: WebPage.NavigationDeciding {
func decidePolicy(for action: WebPage.NavigationAction) async -> WKNavigationActionPolicy {
// Ваша логика обработки переходов
return .allow
}
}

...

let config = WebPage.Configuration()
let decider = CustomNavigationDecider()

WebPage(
configuration: config,
navigationDecider: decider
)



5️⃣ JavaScript-взаимодействие.

let result = try await page.callJavaScript("document.title")
print("Заголовок страницы: \(result)")



Важные особенности:

🔹 Требует iOS 18+ / macOS Sequoia+.
🔹 Для сложной навигации обязателен NavigationStack.
🔹 Поиск по странице: .findNavigator(isPresented: $showSearch).
🔹 История посещений: page.backForwardList.items.


💡 Вывод:

Новый WebView это мощное решение для интеграции веб-контента в SwiftUI-приложения. Он предлагает современный API и полноценную функциональность.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
2215👍7🙏2🔥11
🛡 Certificate Pinning на iOS: как защитить приложение от перехвата данных.

Друзья, привет! Сегодня разберем важную тему — защиту сетевых запросов с помощью certificate pinning. Это обязательная защита для любого приложения, которое работает с пользовательскими данными.


⚠️ Зачем это нужно?

Основная цель — защита от атак «человек посередине» (Man-in-the-Middle). Злоумышленники могут перехватывать ваши запросы, тестировать уязвимости API и даже подменять данные. Проверить уязвимость просто: достаточно запустить Charles или Proxyman и посмотреть, проходит ли трафик вашего приложения через прокси.


🤔 Как это работает?

При HTTPS-соединении сервер предъявляет цепочку сертификатов:

🔸 Корневой сертификат (доверенный, уже есть в системе).
🔸 Промежуточный сертификат.
🔸 Листовой сертификат (конечный, именно его мы будем «пиннить»).


💎 Что пиннить?

🔸 Весь сертификат (просто, но негибко).
🔸 Отпечаток (хеш) сертификата.
🔸 Публичный ключ (самый гибкий вариант).


♣️ Практическая реализация:

1️⃣ Достаем сертификат сервера:


openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null | awk '/-----BEGIN CERTIFICATE-----/{i++} i==1 {print}' > leaf.pem



2️⃣ Добавляем сертификат в проект как ресурс:

Например, в папку Certificates/example.com/leaf.der


3️⃣ Реализуем проверку в URLSessionDelegate:


func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) {
let host = challenge.protectionSpace.host
let trustedCertificates = loadCertificates(for: host) // Ваш метод загрузки

guard let serverTrust = challenge.protectionSpace.serverTrust,
let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0),
trustedCertificates.contains(where: { SecCertificateEqual($0, serverCertificate) })
else {
return (.cancelAuthenticationChallenge, nil) // Блокируем соединение
}

return (.useCredential, URLCredential(trust: serverTrust))
}



Основная проблема:

Сертификаты имеют срок действия (обычно 1 год). Когда вы его обновляете, приложение с пиннингом перестанет работать! Решения:

🔸 Пиннить публичный ключ (если он не меняется).
🔸 Удаленное обновление сертификатов через CloudKit или APNS.
🔸 Использовать несколько сертификатов «про запас».


Советы:

🔹 Всегда тестируйте в режиме разработки с отключенным пиннингом.
🔹 Добавьте механизм аварийного отключения пиннинга.
🔹 Используйте готовые решения (Alamofire, TrustKit), если не хотите велосипедить.


💡 Вывод:

Certificate pinning — это must-have для безопасности приложения. Да, это добавляет сложности, но защита пользовательских данных того стоит.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
22👍14🙏63👀221
Мобильный трудоголик
This media is not supported in the widget
VIEW IN TELEGRAM
👏2010👍3🔥2🤯1
👨‍💻 Жесткая правда об IT: почему айтишники выгорают быстрее всех.

Если вы до сих пор верите, что IT это только кожаные кресла, креатив и зарплаты как в Кремниевой долине, приготовьтесь к жесткому разочарованию. Реальность куда прозаичнее.

За последние годы я наблюдал всю эволюцию IT-карьеры — от восторженных новичков, мечтающих изменить мир, до выгоревших senior'ов, считающих минуты до дедлайна. И сейчас готов рассказать, почему IT это не мечта, а работа со своими правилами, подводными камнями и… возможностями.


1️⃣ «Программист только пишет код».

На самом деле, код это лишь 30% работы. Остальное:

🔹 Созвоны с заказчиками, которые сами не знают, чего хотят.
🔹 Разбор чужих багов и легаси-кода, который страшнее кошмара.
🔹 Чтение документации и бесконечные митинги.
🔹 Общение с ИИ (да, теперь и это часть работы!).


2️⃣ «В IT платят бешеные деньги».

Да, зарплаты выше среднего, но:

🔹 Junior'ы часто получают меньше офис-менеджера.
🔹 Зарплата senior'а в регионах ≈ 230к — это достойно, но не роскошно.
🔹 В аутсорсе клиент платит $50/час, а ты получаешь максимум $25, остальное идет на менеджмент, аренду и прибыль компании.


3️⃣ «Работа в крупной компании — предел мечтаний».

Мечтать о карьере в IT-гигантах — естественно. Но реальность крупных корпораций часто отличается от ожиданий:

🔹 Технологическая лотерея: вас могут перебросить с привычного стека на абсолютно чужую технологию без согласования. Сегодня вы пишете на Swift, завтра поддерживаете legacy-проект на Objective-C.
🔹 Винтик в системе: ваша индивидуальность и амбиции часто не имеют значения. Вы часть огромного механизма, где важнее процессы, чем люди.
🔹 Бессмысленный труд: можно годами работать над проектом, который внезапно закроют «по стратегическим причинам». Ваш код может никогда не увидеть пользователей.


💼 Карьера: рост или иллюзия?

Грейд junior/middle/senior часто зависят не от навыков, а от:

🔹 Политики компании (в продукте растут медленнее, в аутсорсе быстрее).
🔹 Умения продавать себя на собеседованиях.
🔹 Везучести.

Можно быть junior’ом с 3 годами опыта или senior’ом с 2. Все решает компания, а не объективные критерии.


Фриланс: свобода или ловушка?

Мечтать о работе «на себя» естественно, но фриланс в IT это:

🔹 Быть одновременно разработчиком, менеджером и продажником.
🔹 Тратить до 70% времени на поиск клиентов и переговоры.
🔹 Конфликт ролей: то, что вы продали, потом придется делать самим.

Фриланс выгоден только тем, кто умеет продавать.


⚠️ Так что же делать? Как выжить в IT?

🔹 Принять реальность: IT не рай, а работа с плюсами и минусами. Как и любая другая.
🔹 Прокачивать софт-скиллы: умение договариваться, объяснять и продавать идеи важнее знания фреймворков.
🔹 Следить за здоровьем: спорт не опция, а необходимость. Сидячий образ жизни убивает быстрее дедлайнов.
🔹 Не гнаться за грейдом: senior в одной компании ≠ senior в другой. Цените знания, а не звания.
🔹 Рассматривать смежные области: devOps, data engineering, AI.. Там, где больше денег и меньше конкуренции.


💡 Вывод:

IT это не приговор, а осознанный выбор. Да, здесь хватает рутины и выгорания, но именно эта сфера даёт возможность работать откуда угодно, постоянно расти и получать достойный доход.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👀24👍1142🔥1🤯1🙏1
🔢 Swift 6.2 вышел: интересные фичи для практической разработки.

Swift 6.2 — самое значимое обновление языка за последние годы. Рассказываю о самых интересных изменениях и как это повлияет на вашу ежедневную разработку.


🚀 Concurrency: теперь проще и безопаснее.

Главное изменение: больше не нужно постоянно ставить @MainActor. Теперь можно включить режим, где весь код по умолчанию работает на главном потоке:


// Раньше:
@MainActor
func updateUI() {
}

// Теперь:
func updateUI() {
// Автоматически на главном потоке
}


Для тяжелых задач появился @concurrent:


@concurrent
func processImage(_ image: UIImage) async -> UIImage {
// Выполняется в фоне, не блокируя интерфейс
return applyFilters(image)
}



🔒 Безопасность памяти на максимум.

Новые типы для системного программирования:

🔹 InlineArray — массив фиксированного размера в стеке:


struct GameLevel {
var enemies: [100 of Enemy] // Фиксированный размер
}


🔹 Span — безопасный срез данных:


let data = [1, 2, 3, 4, 5]
let slice = Span(data, start: 1, count: 3) // [2, 3, 4]


Строгая проверка памяти: компилятор теперь жестче следит за небезопасными операциями.


⚡️ Улучшения для разработки.

🔹 VS Code теперь официально поддерживается:

🔸 Фоновая индексация.
🔸 Встроенный отладчик LLDB.
🔸 Live-превью документации.

🔹 Быстрая сборка макросов: время clean build уменьшилось в разы.

🔹 Умные предупреждения: можно тонко настраивать:


.target(
name: "MyApp",
swiftSettings: [
.treatAllWarnings(as: .error),
.treatWarning("Deprecated", as: .warning)
]
)



Testing 2.0

🔹 Тестирование крашей:


@Test func appCrashesOnInvalidInput() {
#expect(exitCode: .failure, when: app.processInvalidInput())
}


🔹 Вложения в тестах: добавляйте логи, скриншоты, данные:


@Test func userLogin() {
attach(loginRequestData, name: "Request")
attach(screenshot(), name: "UI State")
}



🌐 Поддержка WebAssembly.

Теперь можно компилировать Swift в Wasm и запускать в браузере:


swift build --target wasm32-unknown-wasip1



🔗 Остальные изменения


💡 Вывод:

Swift 6.2 — это фундаментальный шаг в развитии языка, делающий его безопаснее, быстрее и удобнее для разработчиков.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
12714👍32🔥1🙏1
🌐 Wasm и Swift: мост между нативными и веб-приложениями.

Если вы еще не слышали о WebAssembly (Wasm) — это технология, позволяющая запускать код на любых платформах: в браузере, на сервере, в мобильных приложениях. Think of it as universal bytecode для веба и не только.


🤔 Зачем Wasm Swift-разработчику?

🔸 Кроссплатформенность: один код для iOS, Android, Web и серверов.
🔸 Производительность: скорость выполнения, близкая к нативному коду.
🔸 Безопасность: песочница и изоляция по умолчанию.
🔸 Интероперабельность: работа с JavaScript, C++, Rust.

Как и писал ранее про добавление поддержки Wasm в Swift 6.2 — за лето, с момента анонса, экосистема сделала огромный рывок.


⚙️ Embedded Concurrency:

Работает в двух средах:


# CLI-приложения
swift run --target wasm32-unknown-wasip1

# Браузер через JavaScriptKit
import JavaScriptEventLoop // Для асинхронности в браузере



🗃 CI и пакеты:

Автосборка для основных пакетов Swift:

🔸 swift-algorithms
🔸 swift-collections
🔸 swift-nio
🔸 swift-foundation (теперь входит в SDK)


Вот что уже работает сегодня:

🔹 Сборка комплексных проектов:


swift build --target wasm32-unknown-wasip1


🔹 Использование Foundation (кроме Embedded Swift):


import Foundation
// Работает с URLSession, JSONDecoder и т.д.


🔹 Интеграция с JavaScript:


// Через JavaScriptKit
let result = JSObject.global.document.createElement("div")



Что еще в работе:

🔸 Полная поддержка Embedded Swift Concurrency.
🔸 WASI Preview 2 (wasip2).
🔸 Стабилизация Foundation для Embedded.


💡 Вывод:

Wasm в Swift переходит из стадии эксперимента в production-ready. Уже сейчас можно собирать реальные проекты — от CLI-утилит до браузерных приложений. Главное преимущество — единая кодобаза для разных платформ.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍39🔥167🤯2🙏111
👨‍💻 iOS 26: почему нативная разработка становится must-have.

С выходом iOS 26 разрыв между нативными и кроссплатформенными решениями стал очевиден как никогда. Новый дизайн Liquid Glass, Apple Intelligence и интерактивные виджеты работают на полную мощность только в нативных приложениях. Flutter и другие кросс-платформенные фреймворки сталкиваются с растущими ограничениями: от задержек в поддержке новых функций до сложностей с интеграцией системных возможностей.


⚠️ Ключевые преимущества натива в iOS 26:

1️⃣ Полная интеграция с системой:

// Liquid Glass работает из коробки
struct ContentView: View {
var body: some View {
Text("Hello iOS 26!")
.glassBackgroundEffect() // Нативный эффект
}
}



2️⃣ Мгновенный доступ к новым API:

🔹 Apple Intelligence.
🔹 Интерактивные виджеты.
🔹 Системные жесты и анимации.
🔹 On-device AI через Core ML.


3️⃣ Высокая производительность:

Нативные приложения работают на 20-30% быстрее Flutter-аналогов благодаря прямому доступу к системным ресурсам.


Ограничения кроссплатформенных решений:

🔸 Задержки обновлений: поддержка новых функций iOS появляется с опозданием на 6-12 месяцев.
🔸 Костыли и обертки: для интеграции с системными API требуются мосты и плагины.
🔸 Визуальные компромиссы: Liquid Glass и кастомные анимации сложно реализовать.
🔸 Рост техдолга: поддержка двух платформ усложняет архитектуру.


Альтернатива — Kotlin Multiplatform, но с нюансами.

Kotlin Multiplatform (KMP) может быть компромиссом для проектов, где критична экономия без полной потери качества:

🔹 Общая бизнес-логика на Kotlin.
🔹 Нативные UI на SwiftUI и Jetpack Compose.
🔹 Снижение затрат на 20-40% без ущерба UX.

НО: даже KMP не даёт 100% преимуществ чистой нативной разработки:

🔸 Задержки с поддержкой новых API iOS: Swift-экосистема обновляется быстрее, чем KMP-компоненты.
🔸 Сложность отладки: бизнес-логика в KMP + нативный UI = два слоя для диагностики проблем.
🔸 Зависимость от JetBrains и Google: в отличие от нативного Swift, который полностью контролируется Apple.
🔸 Ограниченный доступ к iOS-специфичным функциям: особенно в первые месяцы после релиза новой iOS.


💡 Вывод:

iOS 26 сделала нативную разработку не просто выбором, а необходимостью для продуктов, которые хотят оставаться конкурентоспособными. Хотя Flutter остается вариантом для MVP, для долгосрочных проектов с высокими требованиями к UX и производительности нативный стек — самое верное решение.


➡️ Подписаться на канал
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥26👍143🗿3🤝11