Zurück zur Startseite

Manuelles Update von Capacitor-Bundles ohne Stores

Der Artikel beschreibt die manuelle Integration von @capgo/capacitor-updater für OTA-Updates von JS-Bundles in Capacitor-Apps. Code-Beispiele des Providers werden bereitgestellt, Vorbereitung von Archiven über CLI, Überprüfung der Einhaltung der Store-Regeln. Geeignet für Middle-/Senior-Entwickler.

Capacitor: Bundle-Updates ohne Store-Freigaben
Advertisement 728x90

Manuelle Capacitor-Bundle-Updates ohne App-Stores

Mobile Capacitor-Apps erfordern eine vollständige Veröffentlichung in den Stores, selbst für kleine Anpassungen am JS-Code oder der Konfiguration. Ohne Änderungen am nativen Code dauert die Genehmigung in Google Play, RuStore, AppGallery und App Store mehrere Tage. Automatisierung erleichtert den Prozess, aber eine Moderation ist unvermeidlich.

Die Lösung besteht darin, den Inhalt des dist- (oder build- )Verzeichnisses zu aktualisieren, ohne den nativen Teil neu zu kompilieren. Das Plugin @capgo/capacitor-updater ermöglicht den Over-the-Air-Ersatz des Bundles im manuellen oder automatischen Modus.

Einhaltung der Store-Richtlinien

JS-Bundle-Updates sind von allen Plattformen erlaubt, wenn bestimmte Bedingungen erfüllt sind:

Google AdInline article slot
  • Google Play: Interpretierter Code (JS) ist erlaubt, solange er die Richtlinien gegen Ressourcenmissbrauch nicht verletzt.
  • App Store: Heruntergeladener Code ändert nicht den Zweck der App, erstellt keinen Code-Store und umgeht nicht die WebView-Sicherheit.

Diese Bedingungen sind für Capacitor-Hybrid-Apps automatisch erfüllt.

Installation und Einrichtung

Installieren Sie die Abhängigkeiten:

npm i @capgo/capacitor-updater compare-versions

Fügen Sie in capacitor.config.ts hinzu:

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

Der Modus autoUpdate: false aktiviert die manuelle Update-Verwaltung.

Erstellen Sie einen AppUpdateProvider für React (passen Sie an Ihr Framework an):

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

export default AppUpdateProvider;

Update-Logik

Rufen Sie im Provider CapacitorUpdater.notifyAppReady() innerhalb der ersten 10 Sekunden nach dem Start auf – andernfalls tritt ein Fehler auf.

Google AdInline article slot

Holen Sie die Daten der neuesten Release über eine API (GitHub oder interner Service) ab. Vergleichen Sie Versionen mit compare-versions.

Beispiel für einen vollständigen useEffect:

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]);

Bundle-Vorbereitung

Erstellen Sie das Bundle-Archiv strikt mit der Capgo CLI:

npx @capgo/cli bundle zip [appId] --name [myapp]
  • appId aus capacitor.config.ts.
  • Aktualisieren Sie version in package.json vor dem Build.
  • Laden Sie das ZIP auf einen HTTPS-Server hoch (GitHub Releases oder eigenes Hosting).

Der Archiv-Link wird an CapacitorUpdater.download({ url, version }) übergeben.

Nach dem Download löst downloadComplete CapacitorUpdater.set() aus – das Bundle wird ersetzt und die App neu gestartet.

App-Integration

Vollständiger Provider:

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

  // useEffect how vyshe

  return children;
};

In main.tsx umschließen Sie die App:

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

Wichtige Punkte

  • Updates funktionieren nur für JS-Bundles, ohne native Plugins.
  • Das Bundle wird über npx @capgo/cli bundle zip archiviert – andere Methoden sind falsch.
  • Der Aufruf von notifyAppReady() ist innerhalb der ersten 10 Sekunden nach dem Start zwingend erforderlich.
  • Versionsvergleich: compare(currentVersion, newVersion, '<').
  • Selbst gehostetes Capgo – eine Alternative für volle Kontrolle.

— Editorial Team

Advertisement 728x90

Weiterlesen