Как вы оцениваете SwiftUI
Что проверяют
Есть ли у вас взвешенное мнение из практики, а не пересказ презентации WWDC. Интервьюер хочет услышать, где SwiftUI уже удобнее UIKit, где нет, и как минимальная версия iOS влияет на выбор. Следом обычно спрашивают, как вы встраиваете SwiftUI в проект на UIKit и обратно.
Как отвечать
Сформулируйте позицию и подкрепите её конкретикой:
- сильные стороны: интерфейс как функция от состояния, меньше кода на типовые экраны, превью через
#Preview, простые анимации. Виджеты WidgetKit и Live Activities делаются только на SwiftUI; - состояние: с iOS 17 основа это макрос
@Observable, который отслеживает чтение конкретных свойств и перерисовывает только зависящие от них view.ObservableObjectи@Publishedостаются для старых таргетов; - слабые стороны: доступный API определяется минимальной версией iOS, часть возможностей появляется только в свежих релизах. Сложные коллекции, текстовые редакторы, тонкая работа со скроллом и камерой по-прежнему проще в UIKit;
- совместимость:
UIViewRepresentableиUIViewControllerRepresentableвстраивают UIKit в SwiftUI,UIHostingControllerделает обратное. Смешанный проект это норма.
Зрелый вывод звучит так: для нового проекта с таргетом от iOS 17 SwiftUI разумный выбор по умолчанию, UIKit точечно там, где его не хватает.
Нужны ваши примеры: какой экран сделали, где упёрлись в ограничение, как обошли. Если коммерческого опыта со SwiftUI нет, скажите, что пробовали его в своих проектах, и опирайтесь только на то, что реально трогали.
Где спотыкаются
Говорят, что SwiftUI сырой и не годится для продакшена. Это устаревшее мнение: новые системные возможности вроде виджетов Apple выпускает сразу под SwiftUI.
Обещают один код на все платформы Apple. Общая база есть, но интерфейс под macOS и watchOS всё равно адаптируют.
Не понимают владение состоянием. Объект, созданный прямо в @ObservedObject var model = Model(), пересоздаётся при перерисовке родителя, владельцем должен быть @StateObject, а с @Observable это @State. Отсюда случайные сбросы данных и лишние перерисовки, которые ловят через Self._printChanges().