Разработка
iOS-разработка становится сложнее — обсуждение на Reddit
Опубликовано
1 год назад/
Обсуждение в Reddit:
Я надеюсь, что у меня аномальный опыт. Я не программировал для iOS всерьез с 2019 года, но сейчас я снова в гуще событий и… все кажется сложнее? Вот несколько примеров за последнюю неделю.
Я скачал пример приложения ScreenCaptureKit, и мне пришлось перепроектировать его, прежде чем я смог понять, что происходит. Все эти биты AsyncThrowingStream/continuation кажутся мне гораздо более запутанными, чем протокол делегата или колбек callback с типом результата.
Отладчику требуется от 2 до 10 секунд на каждый `po`, который я пишу. И это даже если к устройству подключен кабель (и несмотря на подключенный кабель, невозможно снять галочку с ‘connect-via-network’ по cmd+shift+2).
Фреймворки такие сахарные и приятные, но за счет работы ванильных функций Swift. Если я использую обертки свойств SwiftUI, я не могу использовать didSet и willSet. Если я использую макрос Model, я не могу использовать ленивый var, который обращается к self (позже я узнал, что должен использовать обертку свойства Transient).
Я написал крошечный пример приложения SwiftData, и иногда строки, которые я добавляю, сохраняются между запусками, а иногда нет. Оно такое же ванильное, как и все остальные.
Я только что посмотрел Explore structured concurrency in Swift, и у меня голова идет кругом. Перейдите к 8-й минуте и попробуйте разобраться в этом. Когда я завязал с iOS, то, по общему мнению, мы должны были разумно использовать последовательные очереди, а затем отправлять их обратно в основной поток для любой работы с пользовательским интерфейсом. Это оказалось достаточно простым?
Не знаю, может быть, мне просто нужно немного жестких указаний, вроде «все это не так уж и сложно, просто выучи это!». И я выучу. Мне искренне интересно, чувствует ли кто-то еще себя так же, или я один. Я опубликовал в твиттере случайные фрагменты в поисках компании, но у меня не так много iOS-последователей. Что вы все думаете?
Моя личная iOS-история: я написал довольно популярное приложение Joypad в 2009-2010 годах, obj-c до ARC, и с тех пор занимался iOS время от времени. Моя самая продвинутая работа на iOS была в Lyft. Мне кажется, что когда я начинал с Obj-c, язык был довольно простым, а усилия по улучшению доступности (Swift с большим количеством возможностей и приторными DSL) на самом деле усложнили ситуацию.
Ответы:
Пообщавшись со многими инженерами iOS, работавшими в крупных компаниях, и изучив свой собственный опыт, когда я был lead инженером, я чувствую себя тупым и расстроенным. Большинство людей испытывают трудности с темпами изменений всех фреймворков Apple. Я думаю, что есть молчаливое большинство инженеров, которые чувствуют себя так же, и об этом почти не говорят, но их знания устарели. И я думаю, что это одна из причин, по которой Apple пришлось во время WWDC выступить с сильным заявлением о том, что SwiftUI — лучший способ создания приложений.
Лично мне удалось восстановить утраченные позиции благодаря просмотру видеороликов Point-Free. В них рассматриваются все темы: от ванильных до продвинутых, до давайте создадим собственную версию макроса Observable для структур, даже если Apple этого не сделала.
Их способность объяснить выбор Apple и подсмотреть внутреннюю работу новых инструментов помогла мне начать новую карьеру. Мне потребовалось 6 месяцев обучения, чтобы снова почувствовать себя более-менее уверенно. Не знаю, какие у вас цели, но я чувствую вашу боль, найдите учебные ресурсы, которые соответствуют вашей личности, и вы скоро будете в ударе.
Я бы сказал, что большинство из нас не особенно беспокоятся, потому что сосредоточены на конкретных областях. Я много знаю об AVFoundation, но спросите меня о StoreKit (например), и я начну с нуля.
Конечно, через 10 лет все изменится, и сложность возрастет. Посмотрите, на что способны эти устройства.
Что меня беспокоит, так это инструменты для разработчиков, черт возьми, Xcode становится все хуже и хуже.
Apple не знает, каким она хочет видеть Swift. Все новые функции и фреймворки кажутся полуфабрикатами, сломанными, и часто приходится возвращаться к старым парадигмам, потому что Apple не знает, каким вообще должно быть программирование на iOS. Функциональное, реактивное, основанное на наблюдателях? Понятия не имею, но удачи вам в попытках использовать новые API. Все наперекосяк. Такое ощущение, что они постоянно играют в догонялки и пробуют новые блестящие вещи, не доводя их до конца. Combine был многообещающим, но, видимо, Apple внутри компании не рекомендует его использовать в пользу async-await и акторов. Отлично, но это все еще ограничивает вас в работе с устаревшим кодом. Так что Combine отменяется. SwiftUI — это просто ужасный хаос (хотя, конечно, улучшается), но Apple не смогла обеспечить и продумать основные базовые требования, такие как навигация. Это вопиюще. Макросы кажутся странными и совершенно ненужными, если учесть, что остальные API — говно.
Честно говоря, я больше всего радуюсь, когда пишу UIKit-код на базе Swift с некоторыми реактивными парадигмами (может быть, даже использую ReactiveSwift или что-то в этом роде, если чувствую себя авантюристом). У Apple нет четкого и ясного направления, и это вызывает серьезные проблемы, а технологический долг в миллионах кодовых баз медленно растет, потому что Apple не может предоставить четкое направление и ясные, имеющие свое мнение API и фреймворки.
SwiftData — это ненадежный бардак, а менеджер пакетов Swift до сих пор не имеет базовых основных функций, которые были у CocoaPods в течение многих лет, и поэтому почти полностью не поддерживается профессиональными iOS-библиотеками.
Как Apple смогла выпустить UIKit и Foundation, если сейчас все кажется таким мучительным в использовании? Где эргономика для разработчиков, где согласованность между фреймворками, языком и инструментарием?
Не стоит говорить о том, в каком ужасном состоянии находится Xcode. Фантомные ошибки без всяких на то оснований мучают нашу кодовую базу, часто происходят случайные сбои сборки и симулятора, а по сравнению с VsCode или IntelliJ, Xcode смехотворно отстает почти во всех категориях.
Apple нужно что-то исправлять, и очевидно, что у них есть некоторые проблемы в организации платформы разработки.
Да, это становится все труднее.
- Темпы изменений высоки. Из-за этого многие, если не большинство, онлайн-учебников устарели.
- Названия часто путают. У нас были UIWindows и UIViews. Затем UIScenes. Теперь UIWindowScenes и Scenes.
- Отсутствие обратной совместимости с изменениями API значительно усложняет жизнь, если вам приходится поддерживать старые системы.
- Swift приближается по сложности к уровню C++, хотя и с лучшим синтаксисом и защитой.
Сочетание ООП, протоколов, генериков, Combine/React, обёрток свойств, макросов и чёрного ящика, которым является SwiftUI, определенно сложно для разработчиков.
Я согласен с вашей точкой зрения. Я отвлекся от нативного программирования на пару лет, занимаясь Flutter, а когда вернулся, все перевернулось с ног на голову.
Реактивное программирование с комбайном кажется мне вынужденным, я понимаю, как это работает, и все различные виды издателей, но я действительно считаю, что все стало сложнее и неинтуитивнее без особого выигрыша по сравнению с тем, что было раньше. Даже декларативный тип пользовательского интерфейса с SwiftUI, который упрощает прототипирование, кажется мне каким-то кислым, поскольку он оставляет много вопросов без ответа в архитектурном плане о том, как делать определенные вещи или как их тестировать.
Интересная точка зрения. Для контекста, я занимаюсь разработкой iOS, исключительно SwiftUI. Сегодня мне кажется, что все проще, чем когда-либо раньше. Я чувствую, что могу двигаться намного быстрее с сегодняшними фреймворками, и код намного чище. (Особенно использование async/await вместо делегатов. Continuation — это необходимое зло для перехода от одного к другому).
Некоторые части вашего вопроса действительно находят отклик — мне кажется, что Xcode становится хуже. Отладчик очень медленный и ненадежный. Возникают фантомные ошибки. Он очень плохо работает с пакетами Swift, несмотря на то, что это собственное решение Apple. Мне регулярно приходится жертвовать простотой, чтобы заставить его разрешить все мои версии пакетов.
Кроме того, некоторые вещи сейчас очень непрозрачны. Лучшие практики использования параллелизма в Swift мне неизвестны (таски, приоритеты, MainActor vs not и т.д.) Я просмотрел все видео с WWDC, но, как вы и сказали, там полный бардак. Apple не дает реальных примеров, например, сетевых вызовов во ViewModel.
Я также настоятельно рекомендую PointFree.
Я думаю, что они делают все «проще» для начинающих разработчиков, но когда что-то идет не так или что-то не поддерживается, это усложняет ситуацию, поскольку появляется дополнительный уровень абстракции. Для меня Combine и SwiftUI оба кажутся очень сладкими, но я видел много проблем с ними. Даже на форумах разработчиков Apple люди жалуются на них.
Это зависит от того, что вы считаете трудным. В любом случае, когда вы пытаетесь выучить новый язык, который заменяет тот, с которым вам было комфортно работать, это может стать препятствием.
Однако для меня работа с необработанными данными была мучением в Swift, в основном с заменой байтов, упаковкой данных и т.д. Невозможность обернуть структуру в bytes(), как в Python, — это боль, а также некоторые математические функции, например, невозможность возвести в квадрат просто ‘**
‘.
Структурированный параллелизм поначалу пугал, но я обнаружил, что можно создавать обычные функции, не прибегая к try/await. Как только вы столкнетесь с первым «мне нужно, чтобы эта функция ждала такого-то ответа от API», тогда все станет понятно. В Swiftful Thinking есть замечательные видеоролики с объяснениями. Просто погрузитесь и проследите за тем, что он делает на игровой площадке, и у вас все получится.
Будучи знакомым и с UIKit, и с SwiftUI, скажу, что SwiftUI значительно упрощает создание быстрых интерактивных пользовательских интерфейсов, как только вы преодолеете обёртки свойств и синтаксис. Проблемы, с которыми я сталкиваюсь, — это редкие и болезненные ситуации, когда SwiftUI не делает того, что должен, или того, что вам нужно.
SwiftData все еще немного нова, поэтому я обычно даю Apple год или два, прежде чем использовать то, что у них есть. Realm — моя любимая библиотека данных, и она работает очень хорошо.
Я думаю, что в SwiftUI очень легко запутаться. Просто делайте по одному шагу за раз. Посмотрите одно видео о том, чего вы не понимаете, попробуйте это на игровой площадке и продолжайте. Каждый день я продолжаю узнавать что-то новое о Swift и о том, как это реализовать.
Нет. Структурированный параллелизм гораздо чище и проще, чем альтернативы, которые вы могли использовать раньше, такие как блоки диспетчеризации или очереди операций.
Серьезно, сделайте шаг назад и посмотрите на типичное приложение, написанное с использованием libdispatch и колбеков — это запутанный беспорядок. Только потому, что вы знакомы с таким подходом, он кажется нормальным, но после использования async/await вы поймете, что у вас стокгольмский синдром.
Combine сложен, но я думаю, что его можно рассматривать как деталь реализации и в основном игнорировать. Как технология для создания приложений она кажется в лучшем случае тупиковой причудой или уклонением в сторону. Я не вижу никакого реального толчка к ее внедрению со стороны Apple.
SwiftUI значительно упростил и ускорил разработку пользовательского интерфейса для меня. Недавно PO в моем проекте сказала, что я «до смешного быстр», и я отбросил все ее оценки — в основном это заслуга SwiftUI.
То, как я пишу приложения сейчас, совершенно не похоже на то, как я делал это 5 лет назад, а это было совершенно не похоже на то, как я делал это 10 лет назад. То, что вы испытываете, — это технологический отток — вы находитесь в карьере, где вам придется постоянно заново учиться тому, как делать вещи. Я ожидаю, что все снова полностью изменится — возможно, уже скоро мы будем использовать искусственный интеллект для создания приложений.
У меня похожий опыт, и я могу сказать, что сейчас в сообществе гораздо больше «шума».
Избыточные причудливые шаблонные выдаются за откровения, новые концепции, едва появившиеся в бета-версии, проталкиваются как путь вперед.
Хорошая новость заключается в том, что ваши ключевые компетенции по-прежнему актуальны.
Я перенимаю все с умом и тогда, когда чувствую, что это нужно.
Вот, например, я думаю, что:
- Причудливые паттерны проектирования, такие как VIPER — это нелепый оверинжиниринг и глупая трата времени. Нет ничего плохого в MVC, если вы разделяете свои задачи.
- SwiftUI начинает становиться интересным, но я все еще не могу полагаться на него (пока) для серьезной работы.
- SwiftData — слишком новый продукт для меня, чтобы даже рассматривать его, и поскольку это просто Core Data с красивым лицом, вам нужно подумать, нужен ли он вам, и понять, что он дает.
Очень легко почувствовать себя перегруженным и «оставшимся позади», когда у вас был перерыв. Это не значит, что вы отстой.
О, и отладчик — дерьмо, и так было с тех пор, как вышел Swift.
Я считаю, что Swift прошел долгий путь по сравнению со своими ранними итерациями.
Навязывание типобезопасного языка поверх динамичного ядра, в котором все может быть чем угодно, было довольно сложной задачей.
Я считаю, что мы обменяли скорость записи на скорость чтения.
Раньше вы могли набивать NSArray любыми объектами, даже не-NSObject’ами, если знали, что делаете. Так что вы могли написать UITableView, а модель данных могла буквально состоять из одного NSArray. Легко!
Однако через 6 месяцев кто-то новый приходит и добавляет новую функцию, и этот NSArray теперь должен поддерживать мутабельность. А еще через 6 месяцев после этого приходит кто-то новый, не может понять, как все это работает, и переписывает это с каким-то сверхинженерным решением.
Теперь, в новом мире Swift с безопасностью типов, массив должен быть единственным типом, определенным во время компиляции. Таким образом, вы вынуждены заранее продумать, как будет работать ваша модель данных табличного представления. Это, вероятно, означает, что вы не можете просто написать все, что захотите, но это также означает, что вам (через 6 месяцев) и будущим разработчикам будет гораздо проще понять, как добавлять функции без необходимости рефакторить все подряд.
Таков мой опыт в целом. Инструментарий и боль при отладке — все это послужило тому, что кодовая база стала намного проще в использовании и обновлении, чем это было возможно во времена дикого запада.
Мне кажется, что все становится проще. В вашем распоряжении больше инструментов, но вы по-прежнему можете использовать все, что могли в прошлом. Новые вещи современны и решают то, что было болью в прошлом (быстрая итерация при разработке UI, многопоточность/асинхронность…), и я не чувствую, что качество языка ухудшается, Swift всегда был несколько более ориентирован на функциональное программирование, чем на классическое ООП.
Что мне больше всего не нравится, так это разные подходы различных фреймворков, например, WidgetKit дико отличается от всего остального.
Лично я не смотрю туториалы, если мне нужно узнать что-то новое, я читаю документацию, которая часто содержит пример проекта, и этого мне достаточно. Иногда я читаю статью о какой-то новой архитектуре, которую кто-то придумал…
Я не думаю, что это становится сложнее. SwiftUI определенно проще, чем UIKit, в нем меньше шаблонного кода, и он также чрезвычайно интуитивен, как только вы его освоите.
Async/await прост, как только вы поймете, что такое акторы и в каком потоке вы работаете. Если у вас есть сложные операции, которые нужно выполнить, это на 100% проще, чем NSOperation.
Да, выбор очень большой. Я думаю, это потому, что UIKit все еще большой, и в UIKit обычно есть реактивный компонент, такой как RXSwift/Combine.
Однако если посмотреть на то, в каком направлении он движется, то останется SwiftUI и async/await. Оба варианта очень пушистые и дружелюбные.
На новое дерьмо вроде SwiftData я не обращаю особого внимания. Для меня это все равно фигня, так как мне не нужна подобная логика в представлении. Не похоже, что это будет очень полезно прямо сейчас, если только вы не собираете одностраничное приложение со списком леденцов в волшебном ванильном SwiftUI, который они используют в своих демках.