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 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:
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.
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]
appIdauscapacitor.config.ts.- Aktualisieren Sie
versioninpackage.jsonvor 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 ziparchiviert – 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
Noch keine Kommentare.