Переход c Cocoapods на Swift Package Manager

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!



Cocoapods считается наиболее популярным менеджером зависимостей для iOS. Последние годы Apple работает над развитием своего нативного менеджера зависимостей Swift Package Manager (SPM).

Изначально его использование было возможно только для server-side Swift или приложений для терминала. На таких приложениях обкатывали и дорабатывали SPM, комьюнити знакомилось с его работой, а команда Apple получила бета тестеров.

С релизом Xcode 11 SPM начал приходить и в мир разработки под iOS. Сейчас это уже полноценный инструмент, который можно использовать, но пока с ограничениями.

В актуальной версии SPM не поддерживает ресурсы (ждем SE-0271). У нас каждый модуль является атомарной самодостаточной зависимостью, которую можно подключить к проекту, так что ресурсы необходимы (локализации, ассеты).

А пока мы ждем, можно подготовиться к миграции: понять, насколько это сложно, можно ли это автоматизировать и с какими проблемами можно столкнуться.

Зачем мигрировать с Cocoapods на SPM?


  • Нативность и интеграция в экосистему. Уже сейчас Xcode предлагает создать или добавить SPM Package.
  • В отличие от Cocoapods, больше не обязательно иметь workspace для работы над проектом с зависимостями.
  • Добавив новую зависимость, не нужно делать pod install и пересобирать весь проект.
  • Удобно использовать локальные зависимости: не меняется структура папок, быстрее пересобирается.
  • SPM не меняет структуру файла проекта, как это делает Cocoapods, не требует зависимости от Ruby и даже может сгенерировать файл проекта сам (пока недоступно для iOS-проектов).
  • Cocoapods не успевает справляться с нововведениями в Xcode и компилятор Swift.
  • Не нужно создавать проект Example для каждого репозитория: Xcode умеет открывать Package.swift файл как проект.
  • Не нужно оптимизировать дерево зависимостей при помощи abstract_target: SPM из коробки умеет не перекомпилировать код для разных таргетов с общими зависимостями.
  • Можно смотреть blame в зависимостях, а не только в основном проекте.
  • Не нужно писать скрипты на Ruby, чтобы починить конфигурацию проекта.

Как выглядит миграция?


Если ваш проект имеет достаточно много зависимостей, то процесс миграции не сделать за один день. Количество зависимостей в Podfile не равно общему количеству зависимостей, так как одна зависимость может идти в комплекте с еще десятью. Даже если у вас не много зависимостей, но вы разрабатываете свои зависимости, возможно, даже в приватных репозиториях, быстро не мигрировать. К счастью, SPM отлично уживается с Cocoapods, и процесс миграции можно вести итерационно. Главное — учесть нюансы:

  • Не должно быть пересечений между зависимостями SPM и Cocoapods.
  • Миграция должна быть встроена в процесс развития компонентов. Если компонент развивается, поднятие версии должно выполняться как для Cocoapods, так и для SPM.
  • Сложностей для команды быть не должно, а значит, нужно внедрить установку всех зависимостей через единую cli-команду.
  • Миграция должна быть встроена в CI CD. Проект должен собираться как локально так и на агентах CI, во всех конфигурациях.

С чего начать?


Прежде всего собираем полный список ваших зависимостей — он представлен в Podfile.lock. Для этого можно использовать утилиты, например SPMReady.



Далее группируем их по связям. Например, от SMENetwork у нас зависят почти все компоненты, а значит, мы не сможем мигрировать их на SPM, пока не мигрирует сам SMENetwork.

Затем выделяем один модуль, от которого зависит больше всего модулей, — SMENetwork.
И наконец переходим в репозиторий этого модуля, чекаутим его в папку и создаем в руте этой папки модуль.

git clone ssh://.../smenetwork.git Developer/SMENetwork
cd Developer/SMENetwork
swift package init
Creating library package: SMENetwork
Creating Package.swift
Creating Sources/
Creating Sources/SMENetwork/SMENetwork.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/SMENetworkTests/
Creating Tests/SMENetworkTests/SMENetworkTests.swift
Creating Tests/SMENetworkTests/XCTestManifests.swift

В результате мы получаем основной файл Package.swift и папки Sources и Tests. Если они у вас уже были, их не перетрет. Файлы SMENetwork.swift, SMENetworkTests.swift, XCTestManifests.swift, LinuxMain.swift созданы для примера работы Package, их можно удалить.

Файл Package.swift выглядит следующим образом:



Теперь посмотрим на файл SMENetwork.podspec:



Как видно, Sources и Tests лежат в других папках. Перенесем файлы и проверим работоспособность Cocoapods Example проекта.



Добавляем в Package.swift платформу разработки и переносим зависимости из podspec файла сюда. Убеждаемся, что они поддерживают SPM: для этого достаточно проверить, что в Гитхабе есть файл Package.swift. Если его нет и даже нет PR с ним, сделаем PR и поможем Open-Source community.





Для SPM не нужно создавать Example проект: достаточно открыть Package.swift в Xcode и он сам скачает и подключит зависимости, создаст таргеты согласно нашей спецификации. Нам остается только запустить.



В нашем случае почти все заработало из коробки, за исключением одного места, где забыли import Foundation: iOS-разработчики привыкли, что UIKit и Foundation необязательны, ведь работает и без них. Пора отучаться от этой привычки.



Package компилируется, тесты компилируются, но не проходят.



И тут мы упираемся в ограничение отсутствия ресурсов в Package, тесты основаны на моках, которые лежат в json ждем SE-0271…

Итог


Переехать с Cocoapods на SPM несложно. Шаги понятны, но flow монотонен и требует автоматизации.

Без особых усилий исходя из .podspec файла можно создать Package и закоммитить его в репозиторий. А самое главное — можно переехать одним проектом, а другой останется на Cocoapods. Если захочет, конечно.
Источник: https://habr.com/ru/company/tinkoff/blog/491994/


Интересные статьи

Интересные статьи

Блог Cloudflare Недавно мы сменили нашего провайдера капчи с Google reCAPTCHA на сервис независимой компании hCaptcha. Мы рады этому изменению, потому что оно помогает решить про...
Знакомо, узнали? Каждый раз когда вы пытались объявить опциональное замыкание @escaping в Swift компилятор ругался и писал непонятную ошибку @escaping attribute only applies to fun...
Сравнивать CRM системы – дело неблагодарное. Очень уж сильно они отличаются в целях создания, реализации, в деталях.
Если честно, к Д7 у меня несколько неоднозначное отношение. В некоторых местах я попискиваю от восторга, а в некоторых хочется топать ногами и ругаться неприличными словами.
Тема статьи навеяна результатами наблюдений за методикой создания шаблонов различными разработчиками, чьи проекты попадали мне на поддержку. Порой разобраться в, казалось бы, такой простой сущности ка...