С каким технологическим стеком для iOS-разработки вы предпочитаете работать?

Ответ

Гибридный подход UIKit + SwiftUI — оптимален для современных проектов.

  • UIKit: Использую для поддержки legacy-кода, реализации сложных кастомных UI-компонентов (например, своих навигационных контроллеров или высокопроизводительных коллекций) и полного контроля над жизненным циклом.
  • SwiftUI: Выбор для новых greenfield-проектов, быстрого прототипирования и экранов с декларативной логикой. Идеально подходит для современных state-driven интерфейсов.

Пример интеграции:

// Встраивание SwiftUI-вью в UIKit-навигацию
let swiftUIView = MySwiftUIView(viewModel: viewModel)
let hostingController = UIHostingController(rootView: swiftUIView)
navigationController?.pushViewController(hostingController, animated: true)

Архитектура и состояние:

  • MVVM-C: Model-View-ViewModel с Coordinator'ом для управления навигацией и инверсии зависимостей.
  • Управление состоянием: Combine для реактивного биндинга в UIKit-проектах. В SwiftUI-проектах — native @State, @ObservedObject или современный @Observable (iOS 17+). Для асинхронности — Swift Concurrency (async/await).

Дополнительный стек:

  • Хранение данных: CoreData (для сложных моделей), SwiftData (для новых проектов), UserDefaults (для настроек).
  • Сеть: Нативный URLSession с async/await, Alamofire — только в legacy-проектах.
  • Зависимости: Swift Package Manager (SPM) — основной менеджер.

Готов осваивать новые инструменты (SwiftUI, Swift Concurrency, SwiftData) для повышения эффективности разработки.

Ответ 18+ 🔞

А, вот это тема, про которую можно поговорить! Гибридный подход UIKit + SwiftUI — это, блядь, как раз тот самый золотой калибр для проектов, которые не с потолка упали, а живут и дышат.

Смотри, как оно на практике:

  • UIKit: Это наш старый, верный, ворчливый дед в подвале. Его держим для трёх вещей, иначе никак. Первое — поддержка старого кода, который писал ещё тот парень, который уже на Бали. Второе — когда надо выебать мозг дизайнеру и сделать такую кастомную хуйню, что у SwiftUI от перегрузки анимация начнёт тормозить. Свои навигационные контроллеры, коллекции, которые должны летать, а не ползать — это всё сюда. И третье — полный, тотальный контроль над жизненным циклом. Когда надо знать, в какой момент вьюха нахуй с экрана ушла, а не гадать по onDisappear.
  • SwiftUI: А это уже наш шустрый племянник, который только из универа. Берём его, когда начинаем новый проект с чистого листа, или когда надо за полчаса накидать прототип, от которого заказчик обоссытся. Идеально, блядь, подходит для экранов, где логика простая и декларативная. Захотел состояние поменять — обновил @State, и всё само перерисовалось, ёпта. Красота.

Вот, смотри, как их скрестить, чтоб не было мутанта:

// Берём нашу красивую SwiftUI-вьюху...
let swiftUIView = MySwiftUIView(viewModel: viewModel)
// ...и засовываем её в старый добрый UIHostingController, как в скафандр.
let hostingController = UIHostingController(rootView: swiftUIView)
// А потом просто пихаем этот контроллер в нашу UIKit-навигацию. И всё работает!
navigationController?.pushViewController(hostingController, animated: true)

Просто, как три копейки, а работает, блядь.

А теперь про то, как всем этим хозяйством управлять, чтоб не превратилось в свалку:

  • Архитектура: MVVM-C. Model-View-ViewModel, но с довеском в виде Coordinator'а. Зачем? А затем, что навигацию надо вынести нахуй из вьюмоделей и вьюх. Пусть Coordinator этим занимается, а вьюмодель только говорит: «Эй, коорд, нам бы на экран деталей перейти». И всё. Зависимости тоже инвертируем, чтоб не было спагетти-кода.
  • Состояние: Тут два фронта. В мире UIKit — используем Combine. Реактивные пайплайны, биндинги, вся эта магия. В мире SwiftUI — тут уже родные инструменты: @State для мелочи, @ObservedObject для вьюмоделей, а с iOS 17 можно и на новый @Observable пересаживаться. Асинхронщина? Только Swift Concurrency, async/await. Над Future из Combine уже можно смеяться, как над анекдотом.

Ну и по мелочи:

  • Базы данных: Если проект — старый монстр с кучей связей, то CoreData, куда деваться. Если проект новый и хочется попробовать модное — SwiftData. Ну а для какой-нибудь настройки «показывать уведомления» — UserDefaults, и не надо тут.
  • Сеть: Родной URLSession с async/await — это сейчас святое. Alamofire? Только если в проекте он уже есть, и переписывать всё лень.
  • Зависимости: Swift Package Manager (SPM) — наш главный по таблеткам. Карфаген помер, Кокоаподс дышит на ладан. SPM — быстро, нативно и из коробки.

И главное, что я не упёртый ретроград. Если появится какая-нибудь новая хуйня от Apple, которая реально упрощает жизнь — SwiftUI, Concurrency, SwiftData — я первый начну её осваивать и впихивать в продакшн. Лишь бы работало быстрее и не глючило.