По документации Flutter, начиная с версии 3.44, Swift Package Manager включён по умолчанию для нативных зависимостей iOS и macOS, а CocoaPods остаётся резервным вариантом для несовместимых зависимостей (официальная документация Flutter по SwiftPM). Поэтому в 2026 году большинству новых проектов и обычных существующих приложений стоит начинать миграцию, но не удалять старую CocoaPods-схему до успешного Release Archive и готового отката.
Последнее обновление: 14 августа 2026 года. Данные сверены по стабильной документации Flutter 3.44, руководству по Add-to-App, публикации CocoaPods о переходе Trunk в режим только для чтения и официальным инструкциям по настройке iOS.
Эта статья предназначена для вас, если вы обновляете существующее приложение до Flutter 3.44 и не знаете, совместимы ли плагины. Она также пригодится небольшой команде с несколькими Flavor, удалённым Mac, автоматической сборкой или собственными iOS Target. Отдельный раздел посвящён авторам Flutter-плагинов и проектам Add-to-App.
01Решение по типу проекта: мигрировать, оставить двойную схему или подождать
Flutter 3.44 не превращает успешный запуск приложения в доказательство готовности к публикации. Между «зависимости разрешились» и «приложение можно отправлять в App Store» есть несколько отдельных проверок:
- зависимости корректно разрешаются в чистой среде;
- Debug-сборка запускается на симуляторе;
- Release-сборка компилируется;
- Xcode создаёт Archive;
- сертификаты, entitlements и provisioning profile остаются корректными;
- загрузка в App Store Connect проходит предварительную проверку.
Главный риск миграции — не сам Swift Package Manager, а скрытая зависимость проекта от Podfile, Ruby-скриптов, приватных Podspec, дополнительных Target или ручных Build Phases.
| Тип проекта | Решение на август 2026 года | Что сохранить до завершения проверки |
|---|---|---|
| Новый Flutter-проект | Использовать Swift Package Manager по умолчанию | Чистую ветку и зафиксированные версии Flutter/Xcode |
| Обычный существующий проект | Мигрировать отдельной веткой | Podfile, lock-файлы и рабочий CI-сценарий |
| Много плагинов и приватных SDK | Перейти на двойную схему | CocoaPods для несовместимых зависимостей |
| Add-to-App | Проверять отдельно от обычного Flutter-приложения | Рабочую интеграцию хост-приложения |
| Несколько Target, Extension и Flavor | Не удалять CocoaPods до полного Archive-теста | Конфигурации, скрипты и порядок Build Phases |
| Автор плагина | Добавить SwiftPM-описание и сохранить обратную совместимость | Package.swift, podspec и тестовые Target |
Flutter прямо указывает, что при отсутствии поддержки Swift Package Manager зависимость может быть подключена через CocoaPods. Это означает, что промежуточный результат часто будет смешанным: часть библиотек окажется в SwiftPM, часть — в CocoaPods. Удаление Podfile само по себе не является критерием завершённой миграции (руководство Flutter для разработчиков приложений).
02Почему миграция затрагивает не только файл зависимостей
Скрытая привязка к Ruby и Podfile
Старый проект может использовать не только стандартные вызовы pod install. В Podfile часто находятся условные блоки для разных окружений, ручные post_install, изменение deployment target, настройки архитектур и подключение приватного репозитория.
После перехода на SwiftPM эти правила не исчезают автоматически. Некоторые из них нужно перенести в Xcode Build Settings или Build Phases. Другие могут больше не требоваться. Если просто удалить Podfile, вы потеряете часть логики, но не получите эквивалентную конфигурацию.
Несовместимые плагины
Для автора плагина поддержка SwiftPM — это не только добавление файла Package.swift. Нужно проверить исходники, ресурсы, продукт пакета, минимальную версию платформы и тестовые Target. Flutter рекомендует хранить нативные исходники плагина в структуре Swift Package и отдельно описывать зависимости (руководство для авторов плагинов).
Особенно внимательно проверяйте SDK, которые:
- поставляются только через публичный CocoaPods Trunk;
- используют приватные Podspec;
- добавляют ресурсы через
resource_bundles; - требуют ручного копирования Framework;
- содержат Objective-C код и нестандартные настройки линковки.
Изменения в подписи
SwiftPM может изменить способ появления Framework в проекте, но сертификат не «переносится» автоматически между средами. Проблема обычно возникает из-за неправильного Target membership, изменённого Embedded Content, отсутствующего скрипта или несовпадающего Bundle Identifier.
Поэтому проверяйте подпись не только на симуляторе. Симулятор не подтверждает, что Release Archive будет подписан тем же профилем и с теми же entitlements.
Сложные Target и расширения
Widget Extension, Share Extension, Notification Service Extension и внутренние тестовые Target могут иметь отдельные зависимости. В обычном Runner всё будет работать, а Archive завершится ошибкой на другом Target.
Flutter поддерживает интеграцию iOS App Extension, но такой проект нельзя оценивать только по результату flutter run (официальное руководство по iOS App Extensions).
Новые проекты: не возвращайте CocoaPods без причины
Если проект создан уже на Flutter 3.44, базовая рекомендация простая: оставьте сгенерированную SwiftPM-интеграцию. У нового приложения обычно нет накопленного Podfile, нескольких лет Ruby-хака и старых скриптов сборки.
Проверьте каждую новую нативную зависимость:
- Есть ли у плагина инструкция для Swift Package Manager.
- Есть ли в iOS-каталоге плагина
Package.swiftили другой поддерживаемый SwiftPM-маркер. - Совпадает ли минимальная версия iOS с вашим проектом.
- Собирается ли приложение после очистки DerivedData.
- Создаётся ли Release Archive.
Не восстанавливайте CocoaPods только потому, что старый учебник использует pod install. Возвращение к прежней схеме добавляет Ruby-зависимость и оставляет проект на устаревающем пути. При этом Flutter всё ещё рекомендует устанавливать CocoaPods для плагинов, использующих нативный код, поэтому в среде разработчика он может понадобиться даже при SwiftPM по умолчанию (инструкция настройки iOS).
Обычный существующий проект: миграция через отдельную ветку
Для проекта с распространёнными плагинами лучший вариант — не экспериментировать в релизной ветке. Создайте миграционную ветку и зафиксируйте исходное состояние.
Первый шаг: снимите исходные показатели
Сохраните:
- текущую версию Flutter;
- версию Xcode;
- результат
flutter doctor -v; - список пакетов из
pubspec.lock; - Podfile и lock-файл;
- текущие Build Settings;
- успешный лог Release Archive;
- способ подписи и загрузки в App Store Connect.
Храните эти данные рядом с CI-конфигурацией. Иначе после неудачной миграции вы будете сравнивать результаты по памяти.
Второй шаг: обновите Flutter и зависимости
Обновите Flutter до нужной стабильной версии и выполните:
flutter doctor -v
flutter pub get
flutter clean
flutter pub get
Не обновляйте одновременно Flutter, Xcode, все плагины и настройки подписи без фиксации промежуточных состояний. Если сборка сломается, вы не поймёте, какой компонент стал причиной.
Третий шаг: проверьте режим SwiftPM
Проверьте, что SwiftPM не был ранее отключён глобальной настройкой:
flutter config --enable-swift-package-manager
После этого откройте iOS-проект в Xcode и убедитесь, что присутствуют подготовительный скрипт Flutter и зависимость, связанная с автоматически созданным Swift Package. Flutter отмечает, что обновление и запуск проекта могут автоматически добавить SwiftPM-интеграцию (проверка включения SwiftPM).
Четвёртый шаг: сравните Debug и Release
Порядок проверки должен быть именно таким:
- разрешение зависимостей;
- запуск Debug на симуляторе;
- запуск Debug на физическом устройстве;
- сборка Release без подписи;
- Release Archive с подписью;
- экспорт и проверка перед загрузкой.
Сбой на первом шаге означает проблему пакетов. Сбой при компиляции указывает на исходный код или настройки платформы. Ошибка только на Archive чаще связана с подписью, ресурсами, архитектурой или дополнительным Target.
Пятый шаг: сохраните рабочий откат
До подтверждения миграции не удаляйте:
- Podfile;
Podfile.lock;- старые CI-шаги;
- резервную ветку;
- зафиксированную версию CocoaPods;
- инструкции восстановления рабочей среды.
Откат должен проверяться практически. Если вы просто оставили старую ветку, но не запускали её на чистом Mac, это ещё не рабочий план восстановления.
05Плагины, приватные SDK и двойная схема
Если один важный плагин не поддерживает SwiftPM, не пытайтесь насильно перевести весь проект на новый механизм. Сначала определите, является ли CocoaPods временным мостом или постоянной зависимостью.
Для каждой проблемной библиотеки зафиксируйте:
- название и версию;
- источник Podspec;
- публичный или приватный репозиторий;
- наличие ресурсов;
- список Target, где библиотека используется;
- план замены или обновления;
- возможность сборки без доступа к внешнему репозиторию.
Переход Trunk в режим только для чтения запланирован на 2 декабря 2026 года, но это не означает немедленного прекращения уже существующих сборок. CocoaPods указывает, что текущие проекты должны продолжить разрешать существующие зависимости, однако новые версии Podspec после этой даты не будут добавляться в Trunk; опубликованный график может быть изменён (официальный план CocoaPods). Поэтому для критичных SDK заранее фиксируйте версии, используйте собственные источники или готовьте SwiftPM-совместимую замену.
Преимущества двойной схемы
- меньше риск остановить релиз;
- можно мигрировать плагины по одному;
- легче сравнивать результаты;
- остаётся рабочий путь отката.
Недостатки двойной схемы
- сложнее CI;
- больше кэшей и источников ошибок;
- возможны конфликты между CocoaPods и SwiftPM;
- диагностика занимает больше времени;
- новые разработчики дольше осваивают проект.
Смешанная конфигурация — нормальный промежуточный результат. Но её нужно описать в README и воспроизвести на чистом окружении.
06Add-to-App и авторы плагинов: отдельные правила
Обычная миграция Flutter-приложения не переносится один в один на Add-to-App. В существующее iOS-приложение Flutter теперь можно интегрировать через пакет FlutterNativeIntegration. Официальная процедура включает генерацию пакета командой:
flutter build swift-package --platform ios
Затем пакет добавляется в Xcode-проект, настраивается путь FLUTTER_SWIFT_PACKAGE_OUTPUT, задаётся режим сборки и добавляются скрипты подготовки и сборки (руководство Flutter Add-to-App).
Для нестандартных конфигураций Flutter отдельно описывает режимы Debug, Profile и Release. Если ваш Flavor называется иначе, задайте FLUTTER_BUILD_MODE явно. Иначе Xcode может передать конфигурацию, которую Flutter не сопоставит с ожидаемым режимом.
Авторам плагинов нужно протестировать не только собственный пример. Проверьте:
- импорт
Package.swiftв Xcode; - Swift и Objective-C исходники;
- ресурсы и privacy manifest;
- минимальную версию iOS;
- статическую или динамическую линковку;
- тестовый Target;
- потребителя, который ещё использует CocoaPods.
Flutter допускает сохранение CocoaPods-зависимостей для обратной совместимости. Поэтому удалять .podspec сразу после появления Package.swift не следует, если вы поддерживаете пользователей на старых версиях Flutter.
Проверка на удалённом Mac и в CI
Удалённый Mac полезен не как «ускоритель» миграции, а как независимая контрольная среда. На вашем ноутбуке старые DerivedData, SwiftPM-кэши и Ruby-пакеты способны скрыть ошибку.
| Этап проверки | Что выполнить | Какой результат считать успешным |
|---|---|---|
| Исходный код | Клонировать репозиторий заново | Нет локальных файлов, необходимых для сборки |
| Инструменты | Проверить Flutter, Xcode и CLI | Версии совпадают с CI-документацией |
| Dart-зависимости | Выполнить flutter pub get |
Lock-файл не изменился без причины |
| Нативные зависимости | Запустить сборку iOS | SwiftPM и резервные Pod разрешаются |
| Release | Создать Archive | Архив создаётся без ручного исправления |
| Подпись | Проверить сертификат и profile | Entitlements и Bundle Identifier совпадают |
| Публикация | Выполнить preflight-проверку | Нет ошибок до отправки в App Store Connect |
В удалённой среде храните только необходимые секреты. Сертификаты, ключи и токены не должны попадать в исходный код или в открытые логи. Для временной проверки лучше использовать отдельный CI-секрет и ограниченные права.
Если у вас нет отдельного Mac для такого эксперимента, можно арендовать удалённый Mac для тестовой сборки, повторить инструментальную цепочку и затем решить, нужен ли постоянный сервер. Для команды, которая уже поддерживает автоматическую публикацию, полезно заранее сравнить стоимость аренды Mac mini с затратами на собственный постоянно включённый компьютер.
08Чек-лист перед удалением CocoaPods
- [ ] Список Flutter-плагинов проверен на наличие SwiftPM-поддержки.
- [ ] Приватные SDK и источники Podspec перечислены отдельно.
- [ ] Debug-сборка прошла на симуляторе.
- [ ] Debug-сборка прошла на физическом устройстве.
- [ ] Release Archive создан из чистого окружения.
- [ ] Каждый основной Target и Extension проверен отдельно.
- [ ] Подпись, entitlements и provisioning profile совпадают с исходной схемой.
- [ ] CI запускается без локальных Ruby- и SwiftPM-кэшей.
- [ ] Ветка с CocoaPods действительно восстанавливает рабочую сборку.
- [ ] Для несовместимых плагинов записан план обновления или замены.
- [ ] Команда знает, какие зависимости работают через SwiftPM, а какие через CocoaPods.
- [ ] В документации проекта указано, как включить резервный сценарий.
Удаляйте старую схему только после прохождения всех пунктов. Если один критичный плагин всё ещё зависит от CocoaPods, оставьте двойную конфигурацию и планируйте повторную проверку после выхода совместимого обновления.
09Что выбрать именно вам в эту неделю
Если вы создаёте новый Flutter-проект, оставляйте Swift Package Manager и проверяйте каждый добавляемый плагин. Если приложение уже выпускается и использует обычные публичные зависимости, создайте миграционную ветку и проведите полный Release-тест. Если в проекте есть приватные Pod, Add-to-App, несколько Target или сложные скрипты, переходите только через двойную схему.
Не оценивайте результат по одному flutter run. Для публикации важны четыре независимых факта: зависимости разрешаются, код компилируется, Archive создаётся, подпись и загрузка проходят.
Если текущий компьютер не даёт вам отдельной и воспроизводимой macOS-среды, временный удалённый Mac позволит скопировать production-инструменты и сравнить сборку до и после миграции без риска для основной рабочей станции. После успешной проверки вы сможете решить, достаточно ли периодической аренды, или для постоянного CI нужен выделенный Mac mini с ежемесячным доступом. Это практичнее, чем держать нестабильный локальный Hackintosh или удалять CocoaPods до того, как проект доказал готовность к релизу.