Flutter Swift Package Manager: Guía Completa de Migración

El fin de CocoaPods ha comenzado
El 2 de diciembre de 2026, el registro trunk de CocoaPods pasará a ser solo lectura permanente. Esto significa que ya no se podrán publicar nuevos pods ni actualizar los existentes. Es el anuncio del fin práctico de la herramienta de gestión de dependencias de la que los desarrolladores de Flutter iOS han dependido durante casi 10 años.
El equipo de Flutter comenzó a preparar el soporte para Swift Package Manager (SwiftPM) desde 2024. Y en Flutter 3.44, SwiftPM se ha convertido en el gestor de dependencias predeterminado para iOS/macOS. Al ejecutar flutter run, Flutter CLI actualiza automáticamente el proyecto Xcode basándose en SwiftPM.
Este artículo aborda ambas perspectivas:
- Desarrolladores de aplicaciones: Cómo migrar proyectos de Flutter existentes basados en CocoaPods a SwiftPM.
- Autores de plugins: Cómo añadir
Package.swiftpara que los plugins de pub.dev admitan SwiftPM.
Si no realiza la migración ahora, las dependencias de iOS quedarán prácticamente congeladas después de diciembre de 2026.
CocoaPods vs Swift Package Manager: Diferencias clave
| Elemento | CocoaPods | Swift Package Manager |
|---|---|---|
| Entidad gestora | Proyecto de código abierto independiente | Soporte oficial de Apple |
| Archivo de configuración | Podfile |
Package.swift |
| Integración con Xcode | Crea .xcworkspace |
Integración nativa con Xcode |
| Velocidad de compilación | Lenta (preprocesamiento basado en Ruby) | Rápida (nativa) |
| Caché de binarios | Limitada | Integrada (caché .build) |
| Estado posterior a 2026 | Solo lectura (Finalizado) | En desarrollo activo |
| Puntuación en pub.dev | Inicio de penalización | Preferencial |
La mayor ventaja de SwiftPM es su integración nativa con Xcode. No requiere ejecutar pod install por separado y se puede compilar directamente con .xcodeproj en lugar de requerir un archivo .xcworkspace.
Desarrolladores de aplicaciones: Migración automática
Si utiliza Flutter 3.44 o superior, en la mayoría de los casos la migración se realiza automáticamente.
1. Verificar la versión de Flutter
flutter --version
# Verificar si es Flutter 3.44.0 o superior
flutter upgrade # Actualizar si es necesario
2. Activar la migración automática
# Al ejecutarlo en un proyecto existente, Flutter CLI intenta automáticamente la migración a SwiftPM
flutter run
# O activarlo explícitamente
flutter config --enable-swift-package-manager
flutter run # Aplica automáticamente la configuración de SwiftPM en ejecuciones posteriores
Contenido de la migración automática realizada por Flutter CLI:
- Añade la configuración de integración de SwiftPM en
ios/Runner.xcodeproj/project.pbxproj. - Añade la referencia
FlutterGeneratedPluginSwiftPackagea la carpetaios/. - Añade
Run Prepare Flutter Framework Scriptal esquema de compilación de Xcode.
3. Verificar el éxito de la migración
# Verificar en Xcode
open ios/Runner.xcworkspace
# O desde la terminal
cat ios/Runner.xcodeproj/project.pbxproj | grep "FlutterGeneratedPluginSwiftPackage"
# Si esta cadena está presente, la integración con SwiftPM se ha completado
En Xcode, los plugins aparecerán como paquetes SwiftPM en la pestaña Project Navigator → Package Dependencies.
4. Manejo de plugins no compatibles
Si hay plugins que aún no admiten SwiftPM, Flutter CLI mostrará una advertencia:
The following packages have native iOS code but are not compatible with Swift Package Manager:
- some_plugin (version: 1.2.3)
Flutter will use CocoaPods for these plugins only.
En este caso, Flutter realiza un fallback automático: utiliza SwiftPM para los plugins compatibles y CocoaPods para los plugins no compatibles. El archivo Podfile se mantiene tal como está y solo se aplica a los plugins que requieren pod install.
Cómo manejar plugins no compatibles:
- Abrir un issue solicitando soporte para SwiftPM en el repositorio GitHub del plugin.
- Buscar plugins alternativos (verificar la compatibilidad con SwiftPM en pub.dev).
- Contribuir directamente con un PR que añada
Package.swift.
5. Desactivación temporal (en caso de problemas)
Si SwiftPM causa errores de compilación, se puede desactivar temporalmente:
# pubspec.yaml — Desactivación temporal
flutter:
config:
enable-swift-package-manager: false
O bien:
flutter config --no-enable-swift-package-manager
⚠️ Esta opción es una medida de desvío temporal. Se prevé su eliminación alrededor de 2027, por lo que no debe dependerse de ella.
Desarrolladores de aplicaciones: Migración manual (Proyectos heredados)
Si la migración automática falla o se migra un proyecto antiguo, el proceso debe realizarse manualmente.
Lista de verificación previa a la migración
# Hacer copia de seguridad del estado actual
git checkout -b feat/spm-migration
git add -A && git commit -m "chore: before SPM migration"
# Verificar el soporte de SwiftPM para todos los plugins
cat pubspec.yaml | grep -A 50 "dependencies:"
Verifique el distintivo “Swift Package Manager support” en la página de pub.dev de cada plugin de Flutter.
Limpieza del archivo Podfile
# ios/Podfile (Se mantiene para fallback de plugins tras la migración)
platform :ios, '13.0' # Verificar la versión mínima de iOS
# Tras la migración a SwiftPM, los plugins compatibles se excluyen automáticamente
# Especificar plugins utilizados únicamente con CocoaPods (si es necesario)
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
Ejecución de la migración
cd ios
# Limpiar la caché existente de CocoaPods
rm -rf Pods/ Podfile.lock
# Limpieza con Flutter
cd ..
flutter clean
# Reinstalación de dependencias (Uso mixto de SwiftPM + CocoaPods)
flutter pub get
cd ios && pod install # Para plugins que aún lo requieren
cd ..
# Prueba de compilación
flutter build ios --no-codesign
Autores de plugins: Añadir Package.swift
Si distribuye un plugin de Flutter en pub.dev, debe añadir soporte para SwiftPM. El sistema de puntuación de pub.dev ha incluido la compatibilidad con SwiftPM entre sus criterios de evaluación, por lo que no admitirlo provocará una penalización en la puntuación.
Modificación de la estructura de directorios
Estructura original con CocoaPods:
ios/
Classes/
MyPlugin.swift
MyPlugin.h (En caso de uso mixto con Obj-C)
my_plugin.podspec
Estructura tras añadir soporte para SwiftPM:
ios/
my_plugin/ # Raíz del paquete SwiftPM (Novedad)
Package.swift # Manifiesto de SwiftPM
Sources/
my_plugin/ # Nombre del target = Nombre del paquete
MyPlugin.swift
Classes/ # Mantenido para retrocompatibilidad con CocoaPods
MyPlugin.swift
my_plugin.podspec # podspec original mantenido
SwiftPM requiere estrictamente que los archivos de código fuente estén ubicados dentro de la raíz del paquete. CocoaPods permitía rutas fuera de la raíz, pero SwiftPM solo permite rutas estrictamente internas al paquete.
Creación de Package.swift
Para plugins escritos exclusivamente en Swift:
// ios/my_plugin/Package.swift
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "my_plugin",
platforms: [
.iOS(.v13),
],
products: [
.library(
name: "my-plugin",
targets: ["my_plugin"]
)
],
dependencies: [],
targets: [
.target(
name: "my_plugin",
dependencies: [],
path: "Sources/my_plugin",
// En caso de tener dependencias externas de Swift
// dependencies: [
// .product(name: "SomeSDK", package: "some-sdk"),
// ]
)
]
)
Plugin con uso mixto de Swift y Objective-C:
// ios/my_plugin/Package.swift
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "my_plugin",
platforms: [
.iOS(.v13),
],
products: [
.library(name: "my-plugin", targets: ["my_plugin"])
],
targets: [
.target(
name: "my_plugin",
dependencies: [],
path: "Sources/my_plugin",
// Ubicación de las cabeceras públicas de Obj-C
publicHeadersPath: "include",
// Los archivos Obj-C también se incluyen en el mismo target
cSettings: [
.headerSearchPath("include"),
]
)
]
)
SwiftPM no permite combinar Swift y Objective-C dentro del mismo target. Si el plugin utiliza tanto Objective-C como Swift, se deben separar en targets independientes:
targets: [
// Target exclusivo para Objective-C
.target(
name: "my_plugin_objc",
path: "Sources/my_plugin_objc",
publicHeadersPath: "include"
),
// El target Swift depende del target Obj-C
.target(
name: "my_plugin",
dependencies: ["my_plugin_objc"],
path: "Sources/my_plugin"
)
]
Reubicación de la estructura de archivos fuente
# Crear el directorio de fuentes para SwiftPM
mkdir -p ios/my_plugin/Sources/my_plugin
# Copiar el código fuente existente (se mantiene el original para CocoaPods)
cp ios/Classes/MyPlugin.swift ios/my_plugin/Sources/my_plugin/
cp ios/Classes/MyPlugin.m ios/my_plugin/Sources/my_plugin/ # En caso de incluir Obj-C
Añadir la dependencia de Flutter Framework
Al utilizar las API nativas de Flutter (como el protocolo FlutterPlugin o FlutterMethodChannel), se debe especificar el Framework de Flutter como dependencia:
// ios/my_plugin/Package.swift
let package = Package(
name: "my_plugin",
platforms: [.iOS(.v13)],
products: [
.library(name: "my-plugin", targets: ["my_plugin"])
],
dependencies: [
// Añadir la dependencia de Flutter Framework (¡Imprescindible!)
.package(
url: "https://github.com/nicehash/flutter",
from: "1.0.0"
)
],
targets: [
.target(
name: "my_plugin",
dependencies: [
.product(name: "Flutter", package: "flutter")
],
path: "Sources/my_plugin"
)
]
)
Nota: Para la URL oficial de Package.swift de Flutter, utilice la ruta proporcionada por el equipo de Flutter. Flutter CLI inyecta automáticamente la ruta empaquetada dentro del SDK de Flutter durante la ejecución.
Actualización de pubspec.yaml
# pubspec.yaml (Plugin)
name: my_plugin
version: 2.0.0
flutter:
plugin:
platforms:
ios:
# Configuración de CocoaPods (Retrocompatibilidad)
podspec: ios/my_plugin.podspec
# Configuración adicional de SwiftPM
swiftPackage: ios/my_plugin
Verificación: Prueba con la aplicación de ejemplo
# Activar la migración a SwiftPM en la aplicación de ejemplo del plugin
cd example
flutter config --enable-swift-package-manager
flutter run -d iPhone # Dispositivo real o simulador
# Verificar en Xcode
open ios/Runner.xcworkspace
# Si my_plugin aparece en Package Dependencies, la prueba ha sido exitosa
Actualización del pipeline de CI
# .github/workflows/test.yml
- name: Flutter iOS Build (SwiftPM)
run: |
flutter config --enable-swift-package-manager
flutter build ios --no-codesign --simulator
env:
FLUTTER_VERSION: "3.44.0"
# Prueba paralela de compilación clásica con CocoaPods (Verificación de retrocompatibilidad)
- name: Flutter iOS Build (CocoaPods fallback)
run: |
flutter config --no-enable-swift-package-manager
flutter build ios --no-codesign --simulator
Cronograma de migración y niveles de riesgo
| Momento | Evento | Nivel de riesgo |
|---|---|---|
| Flutter 3.44 (Actual) | SwiftPM predeterminado | Bajo (con fallback) |
| 2 de diciembre de 2026 | CocoaPods trunk en solo lectura | Alto |
| Primer semestre de 2027 (Estimado) | Eliminación de la opción de opt-out en Flutter | Muy alto |
Acciones a realizar ahora:
- Desarrolladores de aplicaciones: Realizar pruebas de compilación tras ejecutar
flutter config --enable-swift-package-manager. - Autores de plugins: Publicar una nueva versión en pub.dev tras añadir
Package.swift.
Imprescindible completar antes de diciembre de 2026:
- Verificar el soporte para SwiftPM en todos los plugins en uso.
- Buscar alternativas para plugins no compatibles o contribuir directamente mediante un PR.
Solución de problemas: Errores frecuentes
Error 1: “Sources folder not found”
error: Source files for target 'my_plugin' should be located under 'Sources/my_plugin'
Causa: SwiftPM requiere que los archivos fuente se ubiquen en la ruta Sources/<NombreTarget>/ dentro de la raíz del paquete.
Solución: Mover los archivos fuente a ios/my_plugin/Sources/my_plugin/.
Error 2: “Cannot use Swift and Objective-C in the same target”
Causa: SwiftPM no permite combinar lenguajes dentro del mismo target.
Solución: Separar en un target exclusivo para Obj-C y otro target para Swift.
Error 3: Se sigue utilizando solo CocoaPods incluso tras ejecutar pod install
# Verificar si el modo SwiftPM está forzado
flutter config | grep swift-package-manager
# Si no está activado
flutter config --enable-swift-package-manager
flutter clean && flutter pub get
Error 4: “FlutterGeneratedPluginSwiftPackage not found”
# Limpieza de la caché de Xcode
rm -rf ~/Library/Developer/Xcode/DerivedData
cd ios && xcodebuild -resolvePackageDependencies
Error 5: Advertencias relacionadas con Bitcode
SwiftPM desactiva Bitcode por defecto. Puesto que Apple marcó Bitcode como obsoleto a partir de iOS 16, esta advertencia puede ignorarse.
Impacto en la puntuación de pub.dev
Desde 2025, pub.dev ha incluido la compatibilidad con SwiftPM en la evaluación de la puntuación de los plugins. Categorías de puntuación:
| Nivel de soporte | Impacto en la puntuación de pub.dev |
|---|---|
| Soporte para SwiftPM y CocoaPods | Puntuación máxima |
| Soporte solo para CocoaPods | Penalización (alrededor de -10 puntos) |
| Sin soporte (excepto plugins exclusivamente Dart) | Visualización de advertencias adicionales |
La puntuación de pub.dev, sobre un máximo de 100 puntos, afecta directamente a la posición en los resultados de búsqueda. El soporte para SwiftPM ya no es opcional, sino obligatorio.
Conclusión
El fin de CocoaPods representa uno de los cambios más trascendentales en el ecosistema de Flutter iOS. La transición a Swift Package Manager no es una mera sustitución de herramientas, sino el retorno al ecosistema oficial de Apple.
La buena noticia para los desarrolladores de aplicaciones es que, en la mayoría de los casos, la migración se realiza automáticamente con una sola ejecución de flutter run. Los problemas surgen principalmente al depender de plugins que aún no admiten SwiftPM.
Si es autor de plugins, debe añadir Package.swift de inmediato. A partir de diciembre de 2026, será imposible publicar nuevas versiones en CocoaPods.
Plan de acción:
- Ejecutar
flutter config --enable-swift-package-manager. - Probar la compilación con
flutter run. - Verificar la lista de plugins con advertencias y definir un plan de respuesta.
- (Autores de plugins) Añadir
Package.swifty publicar en pub.dev.
Artículos relacionados: Consulta también la optimización para Android de aplicaciones Flutter en Tamaño de página de 16 KB en Flutter y optimización de Google Play.