Как стать автором
Обновить

Как мы боремся c динамическими библиотеками в Swift. Опыт Яндекса

Время на прочтение 12 мин
Количество просмотров 21K
Всего голосов 54: ↑52 и ↓2 +50
Комментарии 15

Комментарии 15

В итоге остаются только библиотеки swift runtime и vendored-фреймворки

Возможно глупый вопрос, но я под iOS никогда не разрабатывал,
а почему нельзя swift runtime пересобрать из исходников в статическую библиотеку?
Вроде бы исходники доступны?

Действительно, исходники доступны — github.com/apple/swift/tree/master/stdlib
Теоретически собрать их в статическую библиотеку можно. Более того, swiftc принимает флаг -static-stdlib, и он работает для Mac OS ($DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift_static содержит статические либы только для macos)

Но для iOS:
1. Не могу сходу оценить какие переделки Xcode потребуются. Сейчас Xcode все, что касается swift runtime, делает автоматически.
2. Нет гарантий, что стор примет такую сборку. В архиве, отправляемом в стор, лежит папка SwiftSupport, содержащая неподписанные библиотеки swift runtime, т.е. к ним особое отношение
3. В Яндекс.Картах 4 исполняемых файла — основное приложение и три виджета. Если статически влинковать в них рантайм, то размер приложения вырастет на 60-70 мб
  1. В Яндекс.Картах 4 исполняемых файла — основное приложение и три виджета. Если статически влинковать в них рантайм, то размер приложения вырастет на 60-70 мб

А откуда такие цифры, проверяли? При статической линковке в отличие от динамической можно удалить ненужный код (флаг -dead_strip и его аналоги) и вполне возможно что за счет этого суммарный размер уменьшится, а не увеличится, т.к. каждый бинарник возьмет из runtime только малую часть и сумма будет меньше размер всего runtime в виде .so.


Нет гарантий, что стор примет такую сборку. В архиве, отправляемом в стор, лежит папка SwiftSupport, содержащая неподписанные библиотеки swift runtime, т.е. к ним особое отношение

А откуда будут какие-то папки, у вас же будет статическая линковка, кроме как дизасемблированием понять писали ли вы на swift или objective-c не должно быть возможным?

вполне возможно что за счет этого суммарный размер уменьшится, а не увеличится

У нас огромное приложение. Вполне возможно, что стрип библиотеки не даст никакого эффекта.

Кроме как дизасемблированием понять писали ли вы на swift или objective-c не должно быть возможным?

В отличие от Objective-C, все символы Swift заманглены специальным образом и привязаны к модулю, см $nm -gU someBin | xcrun swift-demangle

Есть еще момент — стор рекомпилирует приложение из биткода, и на этот процесс вообще никак нельзя повлиять, только биткод выключить. Но, например, для apple-watch его выключить нельзя.
Apple точно не пропустит такую сборку. Вот здесь явно указано, что в AppStore пропускаются приложения, собранные только с версией свифта, поставляемой с Xcode.

Мне одному кажется, что Свифт слегка недопилен? Особенно как для 3-й версии.

Я к тому, что эта цепочка версий больше похожа не на 1-2-3-4-5, а 0.2-0.4-0.6-0.8-1.0
Любой другой язык за такие хронические breaking changes давно запинали бы ногами. Вон, Python 3 до сих пор вызывает сопротивление, уже который год.

По-настоящему breaking changes были при переходе с Swift 2* на Swift 3*, до сих пор не все перешли. С 3->4 полегче должно быть.
У Питона беда в том, что он интерпретируемый, т.е. скрипты, написанные под 2.х не могут работать, если в системе стоит только 3.х. Свифт позволяет без проблем поддерживать и запускать уже собранные приложения, написанные на 2.0, т.к. рантайм поставляется вместе с самим приложением. Вот когда он станет частью iOS, тогда да, breaking changes не будет больше места. Все это взаимосвязано, если бы Apple интегрировали Swift 1.0 рантайм в iOS сразу, с бинарной совместимостью и прочим, мы бы так до сих пор и навешивали на него костыли. Но они этого не сделали, получив взамен возможность ломать язык практически как угодно, основываясь на опыте и предложениях реальных разработчиков, которые этим языком пользуются. Как только начало получаться то, что более-менее всех устраивает, начали думать о стабилизации. Так что в каком-то смысле да, это 0.1-0.2-0.3, но степень влияния сообщества на развитие языка получилась поразительная, и результат, как по мне, более чем хорош
я и представить себе не мог, сколько проблем нам в итоге доставит Swift

А сколько еще доставит в будущем… Жаль, что ни одна компания, которая решает насильно внедрить Swift в продакшн-разработку, никогда не прислушивается к доводам «не надо, рано еще, подождите, проблем будет больше, чем пользы, остановитесь...». На моей памяти так. Кого ни убеждал — всегда не соглашаются. И лишь собственные грабли, на которые, такое ощущение, каждая компания должна наступить в обязательном порядке при iOS-разработке, «открывает глаза», да и то не всегда, к сожалению. Язык неплох, но рано ему в продакшн для серьезных проектов. Рано. Я сам разрабатываю для iOS еще с 4 ее версии, видел и кодил на всех версиях Swift, и пока еще ничего особо хорошего в нем не увидел, что перекрыло бы сопутствующие минусы.
Да. К сожалению swift на самом деле имеет проблемы. Мы столкнулись у себя и с динамическими библиотеками, и с крашами Xcode (особенно на 2.x версиях), и с долгой компиляцией, и с отваливающимся интелисенс (кстати на obj-c он тоже отваливается), но несмотря на это я считаю это лучше чем писать на obj-c.
Сам язык при должном его понимании позволяет писать код быстрее, безопасней, короче и понятнее что в долгосрочной перспективе экономит уйму времени.
Помимо этого все забывают про то, что код на swift исполняется быстрее в части алгоритмов, нежели чем на obj-c.

На текущий момент не все так плохо:
Xcode падает редко( у меня 6 с obj-c падал чаще)
Интелисенс обычно после переключения файла оживает, но даже без него писать код становиться возможным, из-за более запоминаемого синтаксиса языка.
Непонятные ошибки редкость, и ща частую уже пройденный этап.
Инкрементальная сборка появилась, правда иногда перекомпилирует лишнее.
Осталась 2 проблемы:
Размер приложения, который разбухает на 20-25мб
Долгая загрузка (pre-main), к сожалению у нас в компании это не решили, но статья заставила задуматься о том, что возможно надо было разобраться в этом сильнее.

Кому что важнее то и выбирают. Если команда из 15 человек постоянна сталкивается с кодом любого другого человека, а обьем кода такой, что уже невозможно его весь помнить и приходится его читать, то я лично за swift. С другой стороны если вам важен размер и скорость загрузки, или отсутствуют разработчики способные разобраться в проблеме без google, то всеже лучше obj-c.
Да вот конкретно на моем опыте как-то ни разу не получалось этой самой «долгосрочной перспективы» достаточной длительности, чтобы все сопутствующие разработке проблемы (в основном — потери времени на сборку, подлагивания, частые краши и отвал подсветки — на обжсях да, я изредка ее ловил, но это крайне редко) перекрылись плюсами от свифта. Это не говоря о переходе на новые версии, о потенциальных проблемах с поиском зависимостей, и так далее. Ну и размер, конечно, с загрузкой аппа и пересборкой никто не отменял, тоже верно. Особенно бесит адово долгая архивация приложения, когда приходилось делать проекты в CI — застрелиться можно. По скорости исполнения — вот имхо, на обжси написать приложение, работающее быстро, не составляет никаких проблем, были бы навыки. Да, в свифте, конечно, есть приятные конструкции, упрощающие (хотя иногда и нехило увеличивающие, не будем скромничать, пламенный привет составным генерикам в экстеншенах) код, но потери времени на все вышеперечисленное в моей практике обычно перекрывают экономию в скорости написания кода. Хотя соглашусь с вами, что каждый человек и каждая команда вольны выбирать то, что им больше нравится.
А чем плохи составные generic в extension?
Иногда просто необходимо для базовых протоколов описать функционал с включением или исключением конкретных типов.
Не планируете новый YandexMap Kit представить?
Зарегистрируйтесь на Хабре , чтобы оставить комментарий