Наши статьи

SwiftUI: жизнь без ViewController’ов (не) возможна

SwiftUI: жизнь без ViewController’ов (не) возможна
Всем привет! Я – Junior swift developer и в этой статье я хочу поделиться опытом работы с SwiftUI на коммерческом проекте.
Первый опыт.
Начну немного издалека. До этого у меня не было опыта работы в компании над коммерческими проектами. Полгода назад я осуществил одно из желаний: начал работать, писать на Swift под iOS (моя преданность и любовь к фруктовой компании появилась примерно за 3 года до работы, а программировать начал ещё раньше). Перед устройством нужно было (по обыкновению) сделать тестовое задание. Ограничений тогда не было, а сама задача казалось средней по сложности (это сейчас с текущим опытом её можно сделать за 10-15 минут на коленке, а тогда это было испытанием).
Задача: 3 вкладки таббара.
1 вкладка: отображение данных из бесплатного API (я выбрал numbersapi.com, потому что там интересные факты :) ).
2 вкладка: добавление данных в список из первой вкладки.
3 вкладка: авторизация/регистрация.
Разумеется, на момент выдачи задания я только слышал о SwiftUI, но на практике ни разу не использовал. Ну и сотворил что-то за 2-3 дня на UIKit. После этого получаю ответ: «Сделай на SwiftUI + Combine»
Прекрасно. Мало того, что я понятия не имею, что такое SwiftUI и с чем его едят, так ещё и на десерт – реактивное программирование.
Но задача есть задача. Выполнил. И первый же мой проект был на SwiftUI.
Проект
Надо ли говорить, что вклиниваться в команду сложно, будучи новичком? Так вот и тут. И первая моя задача: добавить тень у NavigationBar. Великий и могучий интернет помогал слабо, так как я сам мало что понимал. Но костыль был готов через день.
Вытерев пот с лица, приступил к другим задачам. Месяц-два монотонной вёрстки и вот я уже клипаю экраны с такой скоростью, будто делаю это с пелёнок. SwiftUI показался мне крайне дружелюбным: никаких тебе CGRect, селекторов и прочего из мира UIKit. Всё, что нужно, ты делаешь в несколько строчек за пару минут. По крайней мере, я так думал до поры до времени…
Задача, разорвавшая шаблон.
Обычное летнее утро. Светит солнышко, птички поют. С улыбкой на лице поднимаюсь в офис. Первая задача: скрыть tabBar при переходе с одного экрана на другой. 0.о
Хорошо, начинаем копаться…
«Ага, так просто задачу не взять… Что говоришь? Библиотеку использовать? Ааа, Introspect. Сейчас попробую»
Ну, полезли смотреть. Ага, на выхлопе замыкания получаем UITabBarController, как интересно. Это что, я в SwiftUI использую контроллеры UIKit? Круто!
Повесив методы Introspect практически на всё, что можно, казалось, я вышел на новый уровень познания. Всё резко заработало как надо: tabBar скрывается, тени везде красивые, даже NavigationBar был исправлен и красиво оформлен. Моему счастью не было предела. Да, Introspect – капля в море, ведь всё остальное делается штатным средствами SwiftUI. Чудесно!
И тут новая задача, ещё красивее прежней.
Авторизация.
Экран авторизации в приложении, tabBar скрыт. Сказано – сделано, уже умеем такое. А как выйти с экрана авторизации? Завершить авторизацию! А если не хочу? Хмм… Надо подумать. Swipe back во спасение. На всех экранах работает (почти), а тут внезапно нет? Полезли копаться: UIViewControllerRepresentable. Я делаю ViewController, а он отображается как самая обыкновенная View в SwiftUI. Забавно, а можно сделать иначе? Да, но только дождись выхода iOS 16.0, а сейчас, мой друг, никак. И да, у тебя не будет работать это, если версия iOS ниже положенной. Веселись с этим. Ну, что делать, только кастомизация. В копилку добавился ещё один момент, где без UIKit не обойтись, да и чёрт с ним. Опять же, это немного, не капля в море (скорее бочка), но также незначительно.
Бросок через бедро.
Карта. Эта та часть программы, где, казалось бы, ну ничто не может пойти не по плану. Добавил карту, добавил аннотации и сиди, попивай пиво кофе. Кластеризация подвела. Нужный объект отображается под второстепенным. Выхода из ситуации два: ждать iOS 100, в котором появится нужная фича, либо кастомизировать. Первый вариант мне не позволил бы делать директор, и я полетел бы с работы как пробка из шампанского, а второй более трудоёмкий. Плак…
Проход на болевой.
Бывают моменты, когда данные нужно подгрузить только один раз при открытии View. А теперь вопрос: какой код выглядит лучше:

или

Думаю, без вопросов: второй вариант, если мы любим красивый код (а чаще мы его любим), более предпочтительный. Сделаем скидку на мой немногочисленный опыт, названия методов можно подобрать лучше, но факт остаётся фактом: второй вариант гораздо чище первого. viewDidLoad гораздо проще понять, нежели отслеживать дополнительную переменную, что она означает, где меняется и прочее. Второе – выбор сильных!
.onArticleWillDisappear
Эта статья не попытка поплакать в жилетку менеджеру проектов или директору и поныть, как всё плохо. Вовсе нет. Цель этой статьи – оглянуться назад, и посмотреть, какая работа была проделана. Взглянуть на стек технологий, принять для себя какое-то решение. Некоторые моменты я упустил, некоторые забыл, а какие-то показались незначительными. Но суть статьи в другом ведь. Задачи в программировании были есть и будут, будут меняться инструменты реализации, будут меняться парадигмы, но в обозримом будущем не будет меняться одно – человек, сидящий перед экраном, который заставляет машину что-то делать. И речь даже не о конкретном лице, нет. Речь о его способности думать и анализировать. Пока ИИ может генерировать пару десятков строк кода, программист создаёт громадные приложения. Дай ему Swift – будет писать на Swift. Посади на Flutter – будет писать на Flutter. Это всего лишь инструменты. Молоток хорош в забивании гвоздей, но плох в вырубке лесов. Также и здесь. SwiftUI – хороший инструмент, позволяющий быстро сделать проект. UIKit, в свою очередь, позволяет выжимать из твоего устройство столько, сколько он не видел с момента появления. SwiftUI + UIKit – отличное сочетание, если знать, что ты делаешь и почему именно так. Но с другой стороны, в SwiftUI не всегда найдётся нужный метод, какие-то замыкания выполнятся не тогда, когда этого хочешь ты и так далее. Сколько бы я не читал статей, не смотрел докладов, многие авторы стоят на одном: за SwiftUI будущее. Но где это будущее? Может, Угвей был прав?
«Прошлое – забыто, грядущее – закрыто, настоящее – даровано»