Pull to refresh
192.64
Rating
TINKOFF
IT’s Tinkoff — просто о сложном

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

TINKOFF corporate blogDevelopment for iOSObjective CXcodeSwift


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. Если захочет, конечно.
Tags:swiftspmdependency manageriOSxcodeswift package managermigration
Hubs: TINKOFF corporate blog Development for iOS Objective C Xcode Swift
Total votes 19: ↑19 and ↓0+19
Views8.2K

Information

Founded
Location
Россия
Website
www.tinkoff.ru
Employees
5,001–10,000 employees
Registered