Flutter dice adiós a CocoaPods: La migración inevitabale a Swift Package Manager
Backend

Flutter dice adiós a CocoaPods: La migración inevitabale a Swift Package Manager

Por qué Flutter abandonará CocoaPods en diciembre de 2026, qué significa para tu proyecto, y cómo migrar sin romper nada.

Por Omar Flores
#flutter #ios #cocoapods #swift-package-manager #mobile #migration

Imagina que diriges una empresa de suministro de agua para una ciudad. Durante décadas, tu sistema ha funcionado. Las tuberías están en todas partes, los desarrolladores de aplicaciones conocen cómo conectarse, hay millones de líneas de documentación sobre cómo usar tu infraestructura.

Pero hace cinco años, empezaste a notar los problemas. Las vulnerabilidades de seguridad aparecen cada vez más seguido. Tu equipo envejece. No hay suficiente dinero para mantenerlo. Así que tomas una decisión: anuncias que dentro de dos años, el sistema viejo dejará de recibir nuevas conexiones. Dentro de tres, cerrará completamente.

Eso es exactamente lo que está sucediendo con CocoaPods en el ecosistema de Flutter.

CocoaPods no desaparecerá mañana. Pero Flutter ya ha decidido: Swift Package Manager es el futuro. El 1 de diciembre de 2026, CocoaPods trunk se volverá de solo lectura. No habrá nuevos pods, no habrá nuevas versiones, no habrá actualizaciones de seguridad. Y aunque tus compilaciones antiguas seguirán funcionando, si necesitas una nueva versión de una dependencia o quieres agregar un plugin nuevo, no podrás. Estarás atrapado.

Para la mayoría de desarrolladores de apps Flutter, esto es apenas un ruido de fondo. El CLI hace la migración automáticamente. Ejecutas flutter run y listo, tu proyecto se actualiza. Pero para los mantenedores de plugins, la historia es completamente diferente. Hoy, el 39% de los top 100 plugins de iOS todavía no ha migrado. Eso significa que cuando CocoaPods cierre, habrá un caos momentáneo en el ecosistema.

Este artículo no es una guía de migración paso a paso. Eso ya existe en la documentación oficial. Este es un análisis de por qué sucede esto, qué significa en realidad, y cómo prepararse para un cambio que parece pequeño pero que es profundo.


El problema que nadie menciona: CocoaPods está en mantenimiento

CocoaPods fue revolucionario hace una década. Proporcionaba gestión de dependencias centralizada para iOS de una manera que Apple nunca ofreció. Funcionó. Millones de apps fueron construidas con él. Los desarrolladores que no tenían que pelear con linkadores y rutas de búsqueda lo amaban.

Pero aquí está la verdad incómoda: CocoaPods fue construido para llenar un vacío que Apple decidió llenar con su propio mecanismo. En 2015, Apple lanzó Swift. Luego, en 2021, Swift Package Manager se integró completamente en Xcode. Ya no es un tercero. Es la herramienta oficial de Apple para gestionar dependencias en el ecosistema Apple.

Eso significa que CocoaPods es ahora un intermediario innecesario.

He visto esto suceder antes en otros ecosistemas. Cuando una herramienta deja de ser la opción canónica, comienza un proceso inevitablemente lento. Los mantenedores no desaparecen de la noche a la mañana. Siguen arreglando cosas. Siguen respondiendo issues. Pero ya no hay energía para grandes cambios. Ya no hay visión a futuro. Es solo mantenimiento.

Y luego, en un momento, los mantenedores deciden: “No, esto es insostenible”. El equipo de CocoaPods escribió un post hace algunos meses: el registry de CocoaPods se volvería de solo lectura. El 1 de diciembre de 2026. No hay negociación. Es una fecha fija.

¿Por qué es importante? Porque significa que en ocho meses, nadie podrá publicar nuevas versiones de pods en el trunk de CocoaPods. Si hoy publicas una versión 2.0 de tu plugin porque encontraste un bug crítico de seguridad, en ocho meses no podrás publicar una versión 2.1. El sistema estará congelado.

Para los desarrolladores de apps, esto es principalmente un inconveniente. Para los mantenedores de plugins, esto es existencial.


Swift Package Manager no es solo un cambio técnico

Swift Package Manager llegó como alternativa, pero es más que eso. Es la dirección que Apple ha decidido tomar. Y cuando Apple decide una dirección, el resto del ecosistema iOS termina siguiendo, eventualmente.

Swift Package Manager tiene ventajas reales. No es solo marketing.

Primero, simplifica la instalación de Flutter. Si eres un desarrollador nuevo en Flutter, hoy necesitas instalar Ruby, luego CocoaPods, luego esperar mientras se descarga todo. Es un punto de fricción importante. Con Swift Package Manager, todo viene integrado en Xcode. Si tienes Xcode, tienes Swift Package Manager.

Segundo, abre acceso al ecosistema entero de Swift packages. Si eres un mantenedor de plugin y necesitas una dependencia, hoy estás limitado a pods que existan en CocoaPods. Con Swift Package Manager, puedes usar cualquier paquete del ecosistema Swift. Eso significa más opciones, mejor código, menos replicación de funcionalidad.

Tercero, la seguridad. No es una característica de Swift Package Manager en sí, pero está vinculada. CocoaPods permite que los pods ejecuten scripts arbitrarios durante la compilación. Es uno de los mayores vectores de ataque en el ecosistema iOS. El equipo de CocoaPods ha pasado los últimos meses bloqueando la capacidad de prepare_command en nuevos pods porque investigadores de seguridad lo estaban abusando constantemente. Swift Package Manager tiene un modelo más restrictivo. Los paquetes pueden hacer menos, pero eso significa que hay menos surface de ataque.

Con todo eso dicho: esto no es un cambio fácil. Es un cambio importante. Toca la base misma de cómo los plugins de Flutter se construyen en iOS.


Lo que cambia para desarrolladores de apps: La buena noticia

Si eres alguien que simplemente construye una app Flutter, necesitas saber esto: probablemente la migración sea completamente automática.

Cuando ejecutes flutter run con Swift Package Manager habilitado, el CLI detectará que tu proyecto no está migrado. Luego actualizará automáticamente tu proyecto para usar Swift Package Manager. Modifica dos archivos:

  • ios/Runner.xcodeproj/project.pbxproj
  • ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Luego, crea un nuevo target: FlutterGeneratedPluginSwiftPackage. Este es el mecanismo que Flutter usa para exponer todos tus plugins como un paquete único de Swift que tu app puede depender.

El CLI también agrega un pre-action en tu esquema Xcode llamado “Run Prepare Flutter Framework Script”. Este script se ejecuta antes de cada compilación, asegurando que las dependencias estén preparadas.

Para la mayoría de apps, eso es todo. Se ve complicado, pero funciona.

El único escenario donde esto se rompe es si tienes plugins que no han migrado a Swift Package Manager. Entonces, Flutter cae de vuelta a CocoaPods para esos específicos. Funciona, pero es un estado temporal. Conforme se acerca el 1 de diciembre de 2026, necesitarás que tus plugins se actualicen o necesitarás cambiarlos.

Existe una salida de emergencia: puedes deshabilitar Swift Package Manager en tu pubspec.yaml:

flutter:
  config:
    enable-swift-package-manager: false

Pero esta es una solución temporal. No es una estrategia a largo plazo.


La verdadera complejidad: Mantenedores de plugins

El cambio fácil es para apps. El cambio difícil es para plugins.

Como mantenedor de un plugin iOS, necesitas hacer varias cosas:

  1. Crear un Package.swift — Define la estructura de tu paquete Swift, las dependencias que necesita, las plataformas que soporta.
  2. Reorganizar tu código — En lugar de tener archivos en ios/Classes/, necesitas moverlos a ios/plugin_name/Sources/plugin_name/.
  3. Actualizar referencias a recursos — Si tu plugin incluye archivos, manifiestos de privacidad, o assets, necesitan estar en el lugar correcto dentro de la estructura de Swift Package.
  4. Actualizar tu pubspec.yaml — Ahora requiere Flutter 3.41 o superior.
  5. Agregar FlutterFramework como dependencia — Si ya migraste tu plugin en 2025, este es el nuevo paso requerido. Flutter agregó un nuevo dependency que todos los plugins necesitan.

Para un plugin simple, esto es un fin de semana de trabajo. Para un plugin complejo con múltiples dependencias de CocoaPods, múltiples recursos, y años de código acumulado, puede ser semanas.

Y aquí es donde el ecosistema tiene un problema real.

Según los datos de Flutter, el 61% de los top 100 plugins de iOS han migrado. El 39% restante está estancado. Algunos están abandonados. Algunos están esperando que sus mantenedores tengan tiempo. Algunos están esperando que sus dependencias migren primero.

Esto crea un efecto dominó. Si tu plugin depende de otro plugin que no ha migrado a Swift Package Manager, tú tampoco puedes completar tu migración. Tienes que esperar. Y mientras esperas, el reloj corre hacia el 1 de diciembre de 2026.

Peor aún: cuando CocoaPods se vuelva de solo lectura, algunos de estos plugins habrán desaparecido del ecosistema práctico. Sus versiones antiguas seguirán existiendo, pero no podrá haber actualizaciones de seguridad, correcciones de bugs, o soporte para nuevas versiones de dependencias.

Para los desarrolladores de apps que confían en plugins estancados, esto significa estar atrapado en una versión antigua del plugin, incapaz de acceder a nuevas funcionalidades o correcciones de seguridad.


Cómo migrar: Para ambos bandos

Para desarrolladores de apps, el proceso es simple:

  1. Actualiza tu Flutter SDK: flutter upgrade
  2. Habilita Swift Package Manager: flutter config --enable-swift-package-manager
  3. Ejecuta tu app: flutter run
  4. El CLI hace el resto

Si algo se rompe, puedes deshabilitarlo globalmente: flutter config --no-enable-swift-package-manager. Pero intenta resolver los problemas primero. Abre un issue con los detalles de qué plugins están causando el problema.

Para mantenedores de plugins, el proceso es más involved. La documentación oficial de Flutter es clara y detallada. Aquí están los pasos principales:

Primero, crea la estructura de directorios:

my_plugin/
  ios/
    my_plugin/
      Package.swift
      Sources/
        my_plugin/

Luego, tu Package.swift debe verse así:

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "my_plugin",
    platforms: [
        .iOS("13.0"),
        .macOS("10.15")
    ],
    products: [
        .library(name: "my-plugin", targets: ["my_plugin"])
    ],
    dependencies: [
        .package(name: "FlutterFramework", path: "../FlutterFramework")
    ],
    targets: [
        .target(
            name: "my_plugin",
            dependencies: [
                .product(name: "FlutterFramework", package: "FlutterFramework")
            ],
            resources: [
                // Si tienes un PrivacyInfo.xcprivacy
                .process("PrivacyInfo.xcprivacy"),
            ]
        )
    ]
)

Nota el nuevo paso: necesitas agregar FlutterFramework como dependencia. Si migraste en 2025, necesitas volver y agregar esto.

Luego, mueve todo tu código de ios/Classes/ a ios/my_plugin/Sources/my_plugin/. Actualiza tus imports en cualquier lugar donde haya referencias relativas.

Si tienes un archivo PrivacyInfo.xcprivacy (y con las nuevas reglas de privacidad de Apple, probablemente lo tengas), muévelo a ios/my_plugin/Sources/my_plugin/PrivacyInfo.xcprivacy.

Actualiza tu pubspec.yaml:

environment:
  sdk: ^3.11.0
  flutter: ">=3.41.0"

Si usas Pigeon para generar código Dart-Swift, actualiza tu configuración de Pigeon:

swiftOut: 'ios/my_plugin/Sources/my_plugin/messages.g.swift',

Finalmente, prueba que tu plugin aún funciona con CocoaPods (para apps que no han migrado):

flutter config --no-enable-swift-package-manager
cd example/
flutter run

Y que funciona con Swift Package Manager:

flutter config --enable-swift-package-manager
flutter run

Errores comunes: Cómo los equipos rompen esto

He visto lo siguiente suceder varias veces:

Error 1: Migrar el plugin pero olvidar FlutterFramework

Si migraste en 2025, your Package.swift probablemente no tiene FlutterFramework. Flutter agregó este requirement en 3.41. Tu plugin compilará, pero fallará en runtime. Los síntomas: “undefined symbol” errors durante linking.

La solución es simple: ve a tu Package.swift y agrega:

dependencies: [
    .package(name: "FlutterFramework", path: "../FlutterFramework")
],
targets: [
    .target(
        name: "my_plugin",
        dependencies: [
            .product(name: "FlutterFramework", package: "FlutterFramework")
        ],
    )
]

Error 2: Abandonar CocoaPods antes de tiempo

Si eres un mantenedor de plugin y migras a Swift Package Manager, pero no actualizas tu documentación, tus usuarios probablemente intentarán usar tu versión nueva con CocoaPods. Fallará de formas misteriosas.

Mantenla ambas. Tu my_plugin.podspec debe apuntar al nuevo lugar de tus archivos:

s.source_files = 'my_plugin/Sources/my_plugin/**/*.swift'

Los usuarios en CocoaPods todavía pueden compilar. Y los usuarios en Swift Package Manager también.

Error 3: Resources en el lugar equivocado

Si tu plugin incluye imágenes, manifiestos de privacidad, o cualquier otro asset, necesita estar dentro de la estructura de Swift Package, no afuera. Si lo pones en el lugar equivocado, Xcode no lo encontrará.

Las resources deben estar dentro de Sources/my_plugin/. Luego, referenciarlas en tu código usando Bundle.module:

#if SWIFT_PACKAGE
    let imagePath = Bundle.module.path(forResource: "myImage", ofType: "jpg")
#else
    let imagePath = Bundle(for: Self.self).path(forResource: "myImage", ofType: "jpg")
#endif

El timeline real: Lo que sucede después

Aquí está la línea de tiempo oficial:

  • Hoy (mayo 2026): Swift Package Manager está habilitado por defecto en Flutter 3.44+. Los desarrolladores pueden optar por no usarlo, pero el futuro es evidente.
  • Septiembre-octubre 2026: El equipo de CocoaPods enviará recordatorios masivos. Más publicidad. Más presión sobre mantenedores de plugins.
  • 1 de noviembre a 7 de noviembre de 2026: CocoaPods hace una “prueba” de ir a solo lectura. Es una ventana de una semana donde el sistema estará en solo lectura para que la automatización pueda fallar temprano.
  • 1 de diciembre de 2026: CocoaPods trunk es permanentemente solo lectura. Ese es el final.

Después del 1 de diciembre:

  • Los plugins existentes en CocoaPods no desaparecerán. Sus versiones antiguas seguirán siendo descargables.
  • Pero no habrá nuevas versiones. Si encontraste un bug de seguridad crítico, no puedes lanzar una parche. Si necesitas actualizar una dependencia para soportar una nueva versión de iOS, no puedes.
  • Los desarrolladores de apps con plugins abandonados estarán atrapados. No podrán actualizar sus plugins. Eventualmente, sus apps envejecerán y dejarán de funcionar en nuevas versiones de iOS.

El 1 de diciembre no es el fin del mundo. Pero es el fin de una era. Y es mejor prepararse ahora que estar en pánico el 2 de diciembre.


La migración no es opcional. Es solo una cuestión de cuándo aceptas que el futuro llegó, no cuándo lo niegas.