Si tu app Ionic/Angular todavia tiene paquetes cordova-plugin-* en el lockfile, eso suele ser lo que hoy te esta bloqueando una actualizacion de Xcode o del target SDK de Android -- la mayor parte de ese ecosistema quedo sin mantenimiento real desde 2021-2022, y Capacitor es el runtime por defecto de Ionic desde la v6. La buena noticia: los plugins que aparecen en casi toda app Ionic antigua -- camara, geolocalizacion, splash screen, status bar, notificaciones locales, estado de red -- tienen reemplazos directos en Capacitor y con mantenimiento activo. La migracion es mecanica en la mayor parte. Un par de puntos se rompen de verdad.
mapa plugin por plugin
| Plugin Cordova | Reemplazo Capacitor | Que cambia realmente |
|---|---|---|
| cordova-plugin-camera | @capacitor/camera | Basado en promesas en vez de callbacks; la clave de Info.plist en iOS no cambia |
| cordova-plugin-geolocation | @capacitor/geolocation | El id de watchPosition ahora es string, no numero |
| cordova-plugin-splashscreen | @capacitor/splash-screen | La config pasa de las etiquetas <preference> a capacitor.config.ts |
| cordova-plugin-statusbar | @capacitor/status-bar | El estilo ahora es un enum con nombre, no un booleano |
| cordova-plugin-local-notification | @capacitor/local-notifications | La programacion usa un objeto trigger en vez de una fecha at suelta |
| cordova-plugin-network-information | @capacitor/network | Las constantes Connection.* desaparecen; el tipo de conexion es un string union |
cordova-plugin-camera → @capacitor/camera
Antes:
navigator.camera.getPicture(
(imageData) => { this.photo = 'data:image/jpeg;base64,' + imageData; },
(err) => { console.error(err); },
{ quality: 75, destinationType: Camera.DestinationType.DATA_URL }
);
Despues:
import { Camera, CameraResultType } from '@capacitor/camera';
const photo = await Camera.getPhoto({
quality: 75,
resultType: CameraResultType.Base64,
});
this.photo = `data:image/jpeg;base64,${photo.base64String}`;
El punto donde se rompe no es la forma de la API, es Android. Si tu platforms/android/AndroidManifest.xml tenia permisos o entradas de FileProvider agregadas a mano, eso vivia en una carpeta que Cordova regeneraba en cada build, y Capacitor no la toca de la misma manera -- hay que volver a agregar esas entradas en el android/app/src/main/AndroidManifest.xml real y permanente que ahora vive en tu repo.
cordova-plugin-geolocation → @capacitor/geolocation
Antes:
navigator.geolocation.watchPosition(
(pos) => this.updatePosition(pos.coords),
(err) => console.error(err),
{ enableHighAccuracy: true }
);
Despues:
import { Geolocation } from '@capacitor/geolocation';
const watchId = await Geolocation.watchPosition(
{ enableHighAccuracy: true },
(position, err) => {
if (position) this.updatePosition(position.coords);
}
);
// mas tarde
await Geolocation.clearWatch({ id: watchId });
El punto de ruptura: watchId ahora es string, no numero. El codigo que lo guardaba en un number[], o lo usaba como clave numerica de un mapa, falla en silencio en un proyecto sin TypeScript en modo estricto -- que es el caso de muchas apps Ionic antiguas.
los puntos de ruptura comunes, mas alla de un plugin puntual
- Los callbacks se vuelven promesas. Todo lo que asumia un callback de sensacion sincrona dentro de un binding de template de Angular merece una segunda mirada a la deteccion de cambios -- las respuestas del puente nativo a veces llegan fuera de la zona de Angular, y un valor que en silencio nunca actualiza la UI suele ser un
NgZone.run()faltante, no un plugin roto. - La carpeta
platforms/desaparece.platforms/androidyplatforms/iosde Cordova, con lo que hayas editado a mano enAndroidManifest.xml,Info.plisto el Podfile, no existen en el modelo de Capacitor. Los proyectos nativos (android/,ios/) se suben al repo y se editan de forma permanente -- encontra cada edicion manual en el viejo arbolplatforms/antes de borrarlo, porque despues se pierde. - Los hooks no tienen equivalente directo. Las entradas
<hook>deconfig.xml(scripts debefore_build,after_prepare) hay que migrarlas al ciclo de vida nativo propio de un plugin de Capacitor, o a un scriptpostbuildde npm comun. - Las variables de plugin desaparecen. Los valores
<preference name="...">de Cordova, pasados como--variableal instalar, no tienen un mecanismo equivalente en tiempo de instalacion -- esos valores pasan acapacitor.config.ts.
pasar config.xml a capacitor.config.ts
Antes:
<preference name="SplashScreenDelay" value="3000" />
<preference name="StatusBarStyle" value="lightcontent" />
<allow-navigation href="https://api.myapp.com/*" />
Despues:
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.codeceibe.myapp',
appName: 'MyApp',
webDir: 'www',
server: {
allowNavigation: ['api.myapp.com'],
},
plugins: {
SplashScreen: {
launchShowDuration: 3000,
},
StatusBar: {
style: 'DARK',
},
},
};
export default config;
un orden de migracion que no te deja la build rota a mitad de camino
- Agrega Capacitor junto a tus dependencias Cordova existentes (
ionic integrations enable capacitor) sin sacar nada todavia -- ambos pueden convivir un rato. - Cambia los plugins de a uno, empezando por el menos usado en la app, y hace una build real a dispositivo despues de cada cambio en vez de agruparlos.
- Una vez que todos los plugins estan cambiados y los dos proyectos nativos compilan limpio desde
android/yios/, sacaplatforms/y las dependenciascordova-*que queden. - Borra
config.xmlal final, solo cuando cada ajuste que tenia ya tiene un lugar confirmado encapacitor.config.tso directamente en los archivos del proyecto nativo.
Hacerlo en ese orden significa que si un paso falla, te queda una app funcionando en el stack viejo, no una a medio migrar que no compila para ninguna de las dos plataformas.
