Volver al inicio

Actualización manual de paquetes de Capacitor sin tiendas

El artículo describe la integración manual de @capgo/capacitor-updater para actualizaciones OTA de paquetes JS en apps de Capacitor. Se proporcionan ejemplos de código del proveedor, preparación de archivos mediante CLI, verificación de cumplimiento con las reglas de las tiendas. Adecuado para desarrolladores middle/senior.

Capacitor: actualizaciones de paquetes evitando aprobaciones de tiendas
Advertisement 728x90

Actualizaciones Manuales de Bundles de Capacitor Sin Tiendas de Aplicaciones

Las apps móviles de Capacitor requieren una publicación completa en las tiendas incluso para ajustes menores en el código JS o la configuración. Sin cambios en el código nativo, la aprobación en Google Play, RuStore, AppGallery y App Store toma días. La automatización ayuda, pero la moderación es inevitable.

La solución es actualizar el contenido del directorio dist (o build) sin reconstruir la parte nativa. El plugin @capgo/capacitor-updater permite el reemplazo de bundles over-the-air en modo manual o automático.

Cumplimiento de las Políticas de las Tiendas

Las actualizaciones de bundles JS están permitidas por todas las plataformas si se cumplen las condiciones:

Google AdInline article slot
  • Google Play: El código interpretado (JS) está permitido siempre que no viole las políticas de abuso de recursos.
  • App Store: El código descargado no cambia el propósito de la app, no crea una tienda de código y no evade la seguridad de WebView.

Estas condiciones se cumplen automáticamente para las apps híbridas de Capacitor.

Instalación y Configuración

Instala las dependencias:

npm i @capgo/capacitor-updater compare-versions

En capacitor.config.ts añade:

Google AdInline article slot
plugins: {
  CapacitorUpdater: {
    autoUpdate: false,
  },
},

El modo autoUpdate: false habilita la gestión manual de actualizaciones.

Crea un AppUpdateProvider para React (adáptalo a tu framework):

const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
  return children;
};

export default AppUpdateProvider;

Lógica de Actualización

En el provider, llama a CapacitorUpdater.notifyAppReady() dentro de los primeros 10 segundos de inicio — de lo contrario, se produce un error.

Google AdInline article slot

Obtén los datos del último lanzamiento vía API (GitHub o servicio interno). Compara versiones usando compare-versions.

Ejemplo de un useEffect completo:

useEffect(() => {
  if (appRelease === null) {
    dispatch(getAppRelease({ type: ReleaseType.APP, last: true }));
  } else {
    const downloadBundle = async () => {
      dispatch(setAppUpdating(true));
      return CapacitorUpdater.download({
        url: APP_BUNDLE_DOWNLOAD_LINK,
        version: appRelease.version,
      });
    };

    CapacitorUpdater.addListener('downloadComplete', async ({ bundle: downloadedBundle }) => {
      try {
        await CapacitorUpdater.set(downloadedBundle);
        dispatch(setAppUpdating(false));
      } catch (e) {
        console.error(e);
        dispatch(setAppUpdating(false));
      }
    });

    if (compare(String(version), appRelease.version, '<')) downloadBundle();

    return () => {
      CapacitorUpdater.removeAllListeners();
      App.removeAllListeners();
    };
  }
}, [appRelease]);

Preparación del Bundle

Crea el archivo del bundle estrictamente usando Capgo CLI:

npx @capgo/cli bundle zip [appId] --name [myapp]
  • appId de capacitor.config.ts.
  • Actualiza version en package.json antes de construir.
  • Sube el ZIP a un servidor HTTPS (GitHub Releases o tu propio hosting).

El enlace del archivo se pasa a CapacitorUpdater.download({ url, version }).

Después de la descarga, downloadComplete activa CapacitorUpdater.set() — el bundle se reemplaza y la app se reinicia.

Integración en la App

Provider completo:

const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
  CapacitorUpdater.notifyAppReady();
  const dispatch = useAppDispatch();
  const appRelease = useAppSelector(selectAppRelease);

  // useEffect how vyshe

  return children;
};

En main.tsx envuelve App:

root.render(
  <Provider store={store({})}>
    <AppUpdateProvider>
      <App />
    </AppUpdateProvider>
  </Provider>
);

Puntos Clave

  • Las actualizaciones funcionan solo para bundles JS, sin plugins nativos.
  • El bundle se archiva vía npx @capgo/cli bundle zip — otros métodos son incorrectos.
  • Llamar a notifyAppReady() es obligatorio dentro de los primeros 10 segundos de inicio.
  • Comparación de versiones: compare(currentVersion, newVersion, '<').
  • Capgo autoalojado — una alternativa para control total.

— Editorial Team

Advertisement 728x90

Leer después