Последнее время всё чаще слышу этот вопрос. Давайте разберёмся: что на самом деле происходит с мобилкой?
🔸 Найм замер – компании берут только сеньоров, джунам пробиться почти нереально.
🔸 Технологический застой – ничего революционного (после 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🗿4❤1🤔1🤯1
Работа с памятью — одна из самых сложных тем в разработке мобильных приложений. Если не уделять этому внимание, приложение начнёт тормозить, вылетать или даже «съедать» всю память устройства.
Существует два подхода к управлению памятью:
🔹 Реактивный: решаем проблемы по мере их появления. Подходит для небольших проектов с жёсткими дедлайнами, но может привести к серьёзному техдолгу.
🔹 Проактивный: заранее оптимизируем код, используем правильные инструменты и следим за потреблением памяти. Это сложнее, но экономит время в долгосрочной перспективе.
Загрузка больших изображений — частая причина утечек. Что делать?
🔹 Используйте Image I/O для создания миниатюр.
🔹 Загружайте картинки лениво (например, через AsyncImage или Kingfisher).
🔹 Храните ассеты в каталогах — они автоматически оптимизируются под разные устройства.
Core Data хранит изменения в памяти до сохранения (save()). Если откладывать сохранение слишком долго — память заполнится. Если сохранять слишком часто — нагрузка на диск возрастёт. Нужен баланс.
Этот класс позволяет системе автоматически освобождать память при нехватке. Просто оберните в него данные и вызывайте beginContentAccess() при необходимости.
🔹 В SwiftUI используйте LazyVStack и LazyHStack, чтобы загружать элементы только при появлении на экране.
🔹 В коде применяйте lazy var для редко используемых свойств (например, кэшированных изображений).
Они проще в управлении памятью, так как не создают retain-циклов и освобождаются сразу после выхода из области видимости.
🔹 Используйте NSCache — он автоматически очищается при нехватке памяти.
🔹 Избегайте сильных ссылок на большие объекты.
🔹 Реализуйте свою стратегию очистки (например, по времени или частоте использования).
Если данные больше не нужны (например, пользователь ушёл в другой раздел приложения), освобождайте память: останавливайте таймеры, отменяйте запросы, выгружайте тяжелые ресурсы.
🔹 Используйте Memory Graph Debugger в Xcode.
🔹 Проверяйте retain-циклы в замыканиях ([weak self]), делегатах и связях View-ViewController.
🔹 Регулярно запускайте Instruments (Leaks) во время тестирования.
Управление памятью — это баланс между производительностью и потреблением ресурсов. Чем раньше вы начнёте следить за этим, тем стабильнее будет ваше приложение.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤18👍4🙏3🔥2 1
Компания 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
🔥16 4👍3❤1👏1
В Xcode 26 появился революционный подход к работе с многозадачностью: 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
👍16 8❤4🔥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
👍19❤8 5🔥2👀1🫡1
В современных приложениях часто возникает необходимость скрывать конфиденциальную информацию от случайного попадания в скриншоты. SwiftUI предоставляет элегантное решение этой проблемы через комбинацию UIViewRepresentable и системных механизмов защиты.
Основная идея заключается в использовании Secure TextField, который iOS автоматически размывает при попытке захвата экрана. Вот как это можно реализовать:
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) {}
}
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()
}
}
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
👍22❤8 5🔥2🙏2🤝1🫡1
This media is not supported in the widget
VIEW IN TELEGRAM
❤17👍7 4🔥2🙏2
Хочешь быть в курсе самых свежих новостей, полезных советов и уникального контента? Тогда наш канал — именно то, что тебе нужно!
Что ты найдёшь в нашем канале:
Присоединись к нашему дружному сообществу и будь на шаг впереди! Подписывайся на 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
👍12👀6🔥3😁3🗿3🤔1
В Xcode 26 RC добавили ручное включение кеширования компиляции и это может серьезно ускорить вашу разработку.
Теперь можно закешировать результаты компиляции Swift и C-подобных языков. При повторной сборке тех же файлов Xcode будет брать их из кеша, а не пересобирать с нуля.
👨💻 Мое мнение:
Я ждал этой полезной фичи много лет, она особенно важна для больших проектов и при выполнении срочных задач, когда каждая сэкономленная минута на вес золота.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
Если вы до сих пор считаете, что карьерный рост в IT ограничивается сменой компании или добавлением нового фреймворка в резюме, то приготовьтесь к жесткой реальности.
Рынок перенасыщен разработчиками, а кризис заставляет компании не просто оптимизировать команды, а безжалостно отсекать все, что не приносит явной ценности. Сейчас я расскажу, как не просто выжить, а сделать мощный скачок в карьере.
Смена специализации или поиск новой работы это не «попробую, что предложат». Это точечный расчет.
Пример:
Вы backend-разработчик и хотите уйти в Data Engineering. Ваш план:
🔹 Не бросать текущую работу в порыве «ненавижу этот код».
🔹 Составить карту навыков: что уже умеете, чего не хватает, какие проекты можно сделать для портфолио.
🔹 Узнать у рекрутеров, на сервисах по поиску работы или в чатах: какие компании ищут таких гибридных специалистов и под какой стек.
Важно: Не учите всё подряд. Сфокусируйтесь на том, что действительно требуется в вакансиях выше уровня или новой специальности.
Да, ИИ пишет код. Но он не может выстроить архитектуру, прочувствовать продукт или понять бизнес-логику. Его сила в скорости рутины. Ваша в экспертизе.
Как использовать ИИ для роста:
🔹 Поручите ему рутинные задачи: генерация тестов, шаблонного-кода, документации.
🔹 Используйте для изучения нового: «Объясни разницу между Grand Central Dispatch и OperationQueues», получите выжимку, углубляйтесь сами.
🔹 Декомпозируйте сложные задачи: «Как перейти от MVC к VIPER?», получите от ИИ план внедрения, проанализируйте предложенную архитектуру, найдите слабые места и адаптируйте под конкретные нужды вашего проекта.
Компании сокращают дорогих специалистов, но паника делает рынок подвижным. Те, кто уверен в своей ценности, могут найти даже лучшие условия.
Но есть нюансы:
🔹 Не меняйте работу случайным образом. Изучите стек и боли нового работодателя.
🔹 Готовьтесь к сложным техническим собеседованиям, на них стали глубже спрашивать про архитектуру и принятие решений.
🔹 Используйте нетворкинг: 70% крутых вакансий не публикуются, их занимают по рекомендациям.
Нельзя вырасти до архитектора, только прочитав книжки. Нужно делать проекты, ошибаться и исправлять последствия.
Ваш план роста:
🔹 Если хотите сменить специализацию, то начните с внутреннего перехода в компании. Так безопаснее.
🔹 Участвуйте в опенсорсе или создайте свой проект на новом стеке. Это лучше любого резюме.
🔹 Просите фидбек у коллег и менторов, без него вы не увидите слепых зон.
Самостоятельно расти можно, но медленно и с ошибками. Окружение ускоряет рост.
Что делать:
🔹 Найдите ментора, который уже прошёл путь, который вы хотите. Не стесняйтесь предлагать бартер: ваши навыки за его время.
🔹 Ведите блог или выступайте на митапах. Это прокачивает экспертный статус и привлекает предложения.
🔹 Подпишитесь на каналы и чаты, где общаются профессионалы вашей целевой области.
Распыление это главный враг роста. Лучше быть экспертом в одном, чем поверхностным во всем.
Как проверить, туда ли вы растете:
🔹 Сравните свой стек с вакансиями мечты. Уберите лишнее, добавьте недостающее.
🔹 Спросите себя: «Что я сделал за последние 3 месяца, чтобы стать ближе к цели?» Если ответа нет, меняйте тактику.
🔹 Не бойтесь отказываться от проектов или задач, которые не ведут к цели.
2025-2026 год станет временем настоящих профессионалов, а не универсальных специалистов широкого профиля. Успеха добьются те, кто делает ставку на глубокую экспертизу, а не поверхностное знакомство с технологиями. Умение эффективно использовать ИИ для рутинных задач и строить сильное профессиональное сообщество вокруг себя станет ключевым преимуществом.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤27👍15👀3🔥1🙏1 1
В Swift есть несколько подходов для работы с потоками и асинхронными задачами. Вот ключевые методы:
Позволяет легко выполнять код в фоне или на главном потоке.
// Фоновый поток
DispatchQueue.global().async {
// Тяжелые вычисления или сетевые запросы
DispatchQueue.main.async {
// Обновляем UI (только в главном потоке!)
}
}
Современный способ для асинхронного кода.
Task {
// Асинхронная работа
let result = await networkRequest()
await MainActor.run {
// Обновляем UI (только в главном потоке!)
updateUI(with: result)
}
}
...
@MainActor
private func updateUI(with result: String) {
}Для сложных зависимостей между задачами.
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👍23 10❤5 2🔥1🤝1
Всем привет! Если вы обновляете свое приложение под iOS 26, то обратили внимание на поиск. Apple серьезно переработала не только визуал, но и логику размещения поисковых интерфейсов.
Рассказываю, как это работает теперь, с живыми примерами и кодом.
Раньше поиск в 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)
Если поиск нужен только в детальном представлении, то модификатор применяется к нему:
NavigationSplitView {
// Список без поиска
} detail: {
NoteDetailView(note: selectedNote)
.searchable(text: $searchText) // Только для детального просмотра
}Здесь тоже работает новое позиционирование: сверху на iPad, снизу на iPhone.
Для приложений с табБаром появился отдельный сценарий. Создаем вкладку с ролью .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 {
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
👍25 12❤4🔥1🤝1 1
Все чаще в интернете возникают споры: одни ребята в восторге от того, как ИИ (тот же Cursor) генерит за них код. Другие, классические разработчики, смотрят на это скептически и даже свысока. Мол, «настоящие программисты так не делают», а вайбкодеры просто копипастят код без понимания. Давайте разбираться.
Если коротко, это когда ты не пишешь код вручную, а объясняешь задачу ИИ «человеческими» словами. А он тебе выдает готовый кусок программы. Это как давать задание умному стажеру, который мгновенно его выполняет.
Идею популяризировал Андрей Карпати (экс-Tesla AI). Его подход: «Я вижу что-то, говорю что-то, запускаю, копирую и это в основном работает». Звучит знакомо, правда?
Недавно мне понадобилось собрать прототип мобильного приложения под iOS с базовым экраном профиля, настройками и простой авторизацией. По старинке я бы потратил день только на то, чтобы прописать основные View, настроить навигацию между экранами и организовать простые сетевые запросы. Но с тем же Cursor я получил готовый каркас на SwiftUI буквально за полчаса. Да, потом я ещё правил логику, допиливал интерфейс и адаптировал под свои нужды. Но самое утомительное, создание базовой структуры, верстка стандартных элементов — всё это за меня сделал ИИ.
И это круто не потому, что я «разленился» или забыл, как пишется код. А потому, что вместо часов кропотливой рутины я сразу смог заняться тем, что действительно важно: проектированием пользовательского опыта, анимациями и продумыванием того, как всё будет работать вместе. ИИ взял на себя черную работу, а я сосредоточился на творческой.
👨💻 О скептическом отношении опытных разработчиков.
Их скепсис мне понятен. Вот пару аргументов, с которыми я сталкивался:
🔸 «Это код низкого качества». ИИ часто выдает работающее, но неоптимальное или небезопасное решение. Без глубоких знаний это не проверить.
🔸 «Таких джунов не возьмут на работу». CEO одной студии прямо заявил, что не стал бы нанимать человека, который просто копипастит код из ИИ без понимания.
И они во многом правы! ИИ это не волшебная палочка. Он не заменит архитектора, который понимает, как строить надежные и масштабируемые системы.
Но вот важный нюанс: многие стартапы уже генерируют по 80-90% кода через ИИ. Но делают это как раз технически сильные основатели, которые могли бы написать всё сами, но теперь экономят время.
Для меня вайбкодинг это не про лень и не про «халяву». Это про эффективность.
🔹 Это смена роли: из «того, кто печатает код» в «того, кто ставит задачи и проверяет результат».
🔹 Это ускорение: можно за день сделать прототип, на который раньше ушла бы неделя.
🔹 Это обучение: ИИ отлично помогает разобраться в новом языке или фреймворке, давая примеры «здесь и сейчас».
Да, ответственность никуда не делась. Код всё так же нужно тестировать, ревьюить и продумывать архитектуру. ИИ не отменяет need-to-know. Но он автоматизирует рутину.
Спор «вайбкодеры vs разработчики» бесполезен. Настоящий прорыв происходит не на этих баррикадах, а у тех, кто использует ИИ как мощный инструмент для усиления своих возможностей.
Не за горами время, когда ценностью будет не умение быстро писать код, а умение чётко ставить задачи ИИ, проверять и дорабатывать результат. Креатив и архитектурное мышление выйдут на первый план.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21👀9🔥4❤2👏1😁1🤯1
На 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)
}
let htmlString = "<h1>Локальный контент</h1>"
page.load(html: htmlString, baseURL: Bundle.main.resourceURL)
VStack {
// Индикатор прогресса
if page.isLoading {
ProgressView(value: page.estimatedProgress)
}
}Регистрация обработчика для собственных URL-схем:
let scheme = URLScheme("myapp")!
var config = WebPage.Configuration()
config.urlSchemeHandlers[scheme] = CustomSchemeHandler()
page = WebPage(configuration: config)Контроль перехода по ссылкам через 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
)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
❤22 15👍7🙏2🔥1 1
Друзья, привет! Сегодня разберем важную тему — защиту сетевых запросов с помощью certificate pinning. Это обязательная защита для любого приложения, которое работает с пользовательскими данными.
Основная цель — защита от атак «человек посередине» (Man-in-the-Middle). Злоумышленники могут перехватывать ваши запросы, тестировать уязвимости API и даже подменять данные. Проверить уязвимость просто: достаточно запустить Charles или Proxyman и посмотреть, проходит ли трафик вашего приложения через прокси.
При HTTPS-соединении сервер предъявляет цепочку сертификатов:
🔸 Корневой сертификат (доверенный, уже есть в системе).
🔸 Промежуточный сертификат.
🔸 Листовой сертификат (конечный, именно его мы будем «пиннить»).
🔸 Весь сертификат (просто, но негибко).
🔸 Отпечаток (хеш) сертификата.
🔸 Публичный ключ (самый гибкий вариант).
openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null | awk '/-----BEGIN CERTIFICATE-----/{i++} i==1 {print}' > leaf.pem
Например, в папку
Certificates/example.com/leaf.der
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
Если вы до сих пор верите, что IT это только кожаные кресла, креатив и зарплаты как в Кремниевой долине, приготовьтесь к жесткому разочарованию. Реальность куда прозаичнее.
За последние годы я наблюдал всю эволюцию IT-карьеры — от восторженных новичков, мечтающих изменить мир, до выгоревших senior'ов, считающих минуты до дедлайна. И сейчас готов рассказать, почему IT это не мечта, а работа со своими правилами, подводными камнями и… возможностями.
На самом деле, код это лишь 30% работы. Остальное:
🔹 Созвоны с заказчиками, которые сами не знают, чего хотят.
🔹 Разбор чужих багов и легаси-кода, который страшнее кошмара.
🔹 Чтение документации и бесконечные митинги.
🔹 Общение с ИИ (да, теперь и это часть работы!).
Да, зарплаты выше среднего, но:
🔹 Junior'ы часто получают меньше офис-менеджера.
🔹 Зарплата senior'а в регионах ≈ 230к — это достойно, но не роскошно.
🔹 В аутсорсе клиент платит $50/час, а ты получаешь максимум $25, остальное идет на менеджмент, аренду и прибыль компании.
Мечтать о карьере в IT-гигантах — естественно. Но реальность крупных корпораций часто отличается от ожиданий:
🔹 Технологическая лотерея: вас могут перебросить с привычного стека на абсолютно чужую технологию без согласования. Сегодня вы пишете на Swift, завтра поддерживаете legacy-проект на Objective-C.
🔹 Винтик в системе: ваша индивидуальность и амбиции часто не имеют значения. Вы часть огромного механизма, где важнее процессы, чем люди.
🔹 Бессмысленный труд: можно годами работать над проектом, который внезапно закроют «по стратегическим причинам». Ваш код может никогда не увидеть пользователей.
Грейд junior/middle/senior часто зависят не от навыков, а от:
🔹 Политики компании (в продукте растут медленнее, в аутсорсе быстрее).
🔹 Умения продавать себя на собеседованиях.
🔹 Везучести.
Можно быть junior’ом с 3 годами опыта или senior’ом с 2. Все решает компания, а не объективные критерии.
Мечтать о работе «на себя» естественно, но фриланс в IT это:
🔹 Быть одновременно разработчиком, менеджером и продажником.
🔹 Тратить до 70% времени на поиск клиентов и переговоры.
🔹 Конфликт ролей: то, что вы продали, потом придется делать самим.
Фриланс выгоден только тем, кто умеет продавать.
🔹 Принять реальность: IT не рай, а работа с плюсами и минусами. Как и любая другая.
🔹 Прокачивать софт-скиллы: умение договариваться, объяснять и продавать идеи важнее знания фреймворков.
🔹 Следить за здоровьем: спорт не опция, а необходимость. Сидячий образ жизни убивает быстрее дедлайнов.
🔹 Не гнаться за грейдом: senior в одной компании ≠ senior в другой. Цените знания, а не звания.
🔹 Рассматривать смежные области: devOps, data engineering, AI.. Там, где больше денег и меньше конкуренции.
IT это не приговор, а осознанный выбор. Да, здесь хватает рутины и выгорания, но именно эта сфера даёт возможность работать откуда угодно, постоянно расти и получать достойный доход.
Мобильный трудоголик
Please open Telegram to view this post
VIEW IN TELEGRAM
👀24👍11❤4 2🔥1🤯1🙏1
Swift 6.2 — самое значимое обновление языка за последние годы. Рассказываю о самых интересных изменениях и как это повлияет на вашу ежедневную разработку.
Главное изменение: больше не нужно постоянно ставить
@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)
]
)
🔹 Тестирование крашей:
@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
1❤27 14👍3 2🔥1🙏1
Если вы еще не слышали о WebAssembly (Wasm) — это технология, позволяющая запускать код на любых платформах: в браузере, на сервере, в мобильных приложениях. Think of it as universal bytecode для веба и не только.
🔸 Кроссплатформенность: один код для iOS, Android, Web и серверов.
🔸 Производительность: скорость выполнения, близкая к нативному коду.
🔸 Безопасность: песочница и изоляция по умолчанию.
🔸 Интероперабельность: работа с JavaScript, C++, Rust.
Как и писал ранее про добавление поддержки Wasm в Swift 6.2 — за лето, с момента анонса, экосистема сделала огромный рывок.
Работает в двух средах:
# CLI-приложения
swift run --target wasm32-unknown-wasip1
# Браузер через JavaScriptKit
import JavaScriptEventLoop // Для асинхронности в браузере
Автосборка для основных пакетов 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🔥16❤7🤯2🙏1 1 1
С выходом iOS 26 разрыв между нативными и кроссплатформенными решениями стал очевиден как никогда. Новый дизайн Liquid Glass, Apple Intelligence и интерактивные виджеты работают на полную мощность только в нативных приложениях. Flutter и другие кросс-платформенные фреймворки сталкиваются с растущими ограничениями: от задержек в поддержке новых функций до сложностей с интеграцией системных возможностей.
// Liquid Glass работает из коробки
struct ContentView: View {
var body: some View {
Text("Hello iOS 26!")
.glassBackgroundEffect() // Нативный эффект
}
}
🔹 Apple Intelligence.
🔹 Интерактивные виджеты.
🔹 Системные жесты и анимации.
🔹 On-device AI через Core ML.
Нативные приложения работают на 20-30% быстрее Flutter-аналогов благодаря прямому доступу к системным ресурсам.
🔸 Задержки обновлений: поддержка новых функций iOS появляется с опозданием на 6-12 месяцев.
🔸 Костыли и обертки: для интеграции с системными API требуются мосты и плагины.
🔸 Визуальные компромиссы: Liquid Glass и кастомные анимации сложно реализовать.
🔸 Рост техдолга: поддержка двух платформ усложняет архитектуру.
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👍14❤3🗿3🤝1 1