upsync 0.1.0
upsync: ^0.1.0 copied to clipboard
Plugin Flutter para descargar y aplicar actualizaciones de Windows en segundo plano.
upsync #
English #
upsync is a Flutter plugin for Windows that keeps a desktop application up to
date by checking a remote manifest, downloading a newer package, and applying
it on restart.
It does three things:
- checks a remote manifest;
- downloads the update when a newer version is available;
- applies the package on restart and relaunches the app.
It does not include a UI. The plugin only handles the background workflow. Your app decides whether to show a badge, a dialog, a "Restart now" button, or to require the user to update.
The plugin currently supports:
- Windows only;
- full release
.zippackages; .exepackages;- Microsoft Store update checks for packaged Store/MSIX apps;
sha256validation when provided by the manifest;- automatic periodic checks;
- restoration of a pending download when the app is opened again.
Getting Started #
1. Install the package #
From pub.dev:
dependencies:
upsync: ^0.1.0
Or directly from GitHub:
dependencies:
upsync:
git:
url: https://github.com/mamm26/flutter_upsync
2. Import the plugin #
import 'package:upsync/upsync.dart';
3. Prepare the required values #
To start upsync, your app needs to know:
- where the manifest is hosted;
- which version is currently installed;
- which build is currently installed;
- optionally, the file name to use for downloaded packages.
Example:
const manifestUrl = 'https://your-domain.com/windows/manifest.json';
const currentVersion = '1.1.1';
const currentBuildNumber = 113;
const appName = 'my_app';
If you do not provide appName, the plugin uses the current executable name.
4. Create the configuration #
final config = UpsyncConfig(
manifestUrl: manifestUrl,
currentVersion: currentVersion,
currentBuildNumber: currentBuildNumber,
appName: appName,
);
Available parameters:
manifestUrlcurrentVersioncurrentBuildNumberappNamecheckIntervalrequestHeadersautoDownloadrequestTimeoutupdateSourceinstallMicrosoftStoreUpdates
Default values:
checkInterval: 30 minutesautoDownload:truerequestTimeout: 45 secondsupdateSource:UpsyncUpdateSource.manifestinstallMicrosoftStoreUpdates:true
5. Start the plugin #
Call it once when your app starts:
await Upsync.instance.start(config);
Simple example:
Future<void> initUpsync() async {
await Upsync.instance.start(
const UpsyncConfig(
manifestUrl: 'https://your-domain.com/windows/manifest.json',
currentVersion: '1.1.1',
currentBuildNumber: 113,
appName: 'my_app',
),
);
}
What start() does:
- validates that the app is running on Windows;
- resolves the local working path;
- restores a pending update if one already exists;
- performs an immediate check;
- schedules periodic checks.
6. Read the state #
Current state:
final state = Upsync.instance.state;
State change stream:
Upsync.instance.states.listen((state) {
if (state.status == UpsyncStatus.downloading) {
print(state.progress);
}
if (state.isReadyToInstall) {
print('An update is ready');
}
});
Available statuses:
UpsyncStatus.idleUpsyncStatus.disabledUpsyncStatus.checkingUpsyncStatus.upToDateUpsyncStatus.updateAvailableUpsyncStatus.downloadingUpsyncStatus.downloadedUpsyncStatus.applyingUpsyncStatus.error
Useful helpers:
final ready = Upsync.instance.state.isReadyToInstall;
final canApply = Upsync.instance.state.canApplyUpdate;
final showIndicator = Upsync.instance.state.showIndicator;
7. Force a manual check #
final state = await Upsync.instance.checkNow();
This is useful if you want to check for updates after login, when opening a screen, or from a button.
8. Apply the update #
When the download is ready:
await Upsync.instance.applyDownloadedUpdateAndRestart();
This method:
- launches the native helper;
- closes the current app;
- applies the package;
- relaunches the app.
9. Clear a pending update #
If you need to remove the downloaded update:
await Upsync.instance.clearPendingUpdate();
This removes:
pending_update.json;- the pending downloaded package, if it exists.
Manifest #
The plugin accepts these keys:
- version:
versionorversionName - url:
url,downloadUrlorexeUrl - build:
buildNumber,buildorversionCode - type:
packageTypeortype - hash:
sha256orchecksum - notes:
notesorreleaseNotes - size:
fileSizeBytesorsize
Recommended example:
{
"version": "1.1.1",
"buildNumber": 113,
"url": "https://your-domain.com/releases/my-app-windows.zip",
"packageType": "zip",
"sha256": "optional_sha256",
"notes": "Optional notes",
"fileSizeBytes": 12345678
}
Required fields:
versionurl
How it decides whether a version is newer:
- if the manifest includes
buildNumberand your configuration includescurrentBuildNumber, it compares those numbers; - otherwise, it compares
versionagainstcurrentVersion.
Supported Packages #
ZIP #
This is the most useful case for Flutter Windows. The zip file can include the release content at the root:
my_app.exe
flutter_windows.dll
data/
Or inside a single folder:
my-app-windows/
my_app.exe
flutter_windows.dll
data/
Both formats are supported.
EXE #
If the manifest points to an .exe, the plugin attempts to replace the current
executable.
Where Files Are Stored #
Base path:
%LOCALAPPDATA%\<app>\updates\
Stored there:
- version-specific subfolders;
- the downloaded package;
pending_update.json.
If you do not provide appName, <app> is derived from the .exe name.
Useful Details Before You Use It #
manifestUrlcannot be empty.autoDownloadis enabled by default.- if
updateSourceisUpsyncUpdateSource.microsoftStore,manifestUrl,currentVersion,currentBuildNumber,requestHeaders,autoDownload,requestTimeout, local downloads,sha256, and the ZIP/EXE helper are not used. Microsoft Store owns the update download and installation. - Microsoft Store checks only work when the app is running with package identity, such as a Store/MSIX install.
- Microsoft Store limits update detection frequency.
upsynckeeps the periodic interval at 30 minutes or more in that mode. - if there is already a valid download for a newer version,
start()restores it without downloading again. - if the manifest includes
sha256, the file is validated before it is marked as ready. - the current public API does not expose a separate manual download method
after setting
autoDownload: false.
Microsoft Store Updates #
Use this mode when the Windows app is distributed through Microsoft Store or as an MSIX package associated with Microsoft Store:
await Upsync.instance.start(
const UpsyncConfig.microsoftStore(),
);
By default, if Microsoft Store reports an update, upsync asks the official
Store API to download and install it. The operating system may show Store
dialogs asking the user to continue. If you only want to detect the update,
disable automatic Store installation:
await Upsync.instance.start(
const UpsyncConfig.microsoftStore(
installMicrosoftStoreUpdates: false,
),
);
When installMicrosoftStoreUpdates is false, checkNow() can move the state
to UpsyncStatus.updateAvailable. You can then call:
await Upsync.instance.applyDownloadedUpdateAndRestart();
In Microsoft Store mode this method delegates to Store installation instead of using a locally downloaded ZIP or EXE.
Minimal Example #
import 'package:flutter/material.dart';
import 'package:upsync/upsync.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Upsync.instance.start(
const UpsyncConfig(
manifestUrl: 'https://your-domain.com/windows/manifest.json',
currentVersion: '1.1.1',
currentBuildNumber: 113,
appName: 'my_app',
),
);
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
Upsync.instance.states.listen((state) async {
if (state.isReadyToInstall) {
await Upsync.instance.applyDownloadedUpdateAndRestart();
}
});
}
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Upsync active'),
),
),
);
}
}
Español #
upsync es un plugin de Flutter para Windows que mantiene actualizada una
aplicación de escritorio mediante la revisión de un manifest remoto, la
descarga de un paquete más reciente y su aplicación al reiniciar.
Hace tres cosas:
- revisa un manifest remoto;
- descarga la actualización si encuentra una versión más nueva;
- aplica el paquete al reiniciar y vuelve a abrir la app.
No trae interfaz. El plugin solo resuelve el trabajo de fondo. Tu app decide si muestra un badge, un diálogo, un botón de "Reiniciar ahora" o si obliga al usuario a actualizar.
Hoy el plugin soporta:
- Windows solamente;
- paquetes
.zipcon el release completo; - paquetes
.exe; - comprobación de actualizaciones con Microsoft Store para apps Store/MSIX;
- validación
sha256si el manifest la trae; - comprobación automática periódica;
- restauración de una descarga pendiente si la app se vuelve a abrir.
Uso desde cero #
1. Instala el paquete #
Desde pub.dev:
dependencies:
upsync: ^0.1.0
O directamente desde GitHub:
dependencies:
upsync:
git:
url: https://github.com/mamm26/flutter_upsync
2. Importa el plugin #
import 'package:upsync/upsync.dart';
3. Prepara los datos que necesita #
Para arrancar upsync, tu app tiene que saber:
- dónde está el manifest;
- cuál es la versión instalada;
- cuál es el build instalado;
- opcionalmente, el nombre con el que quieres guardar las descargas.
Ejemplo:
const manifestUrl = 'https://tu-dominio.com/windows/manifest.json';
const currentVersion = '1.1.1';
const currentBuildNumber = 113;
const appName = 'mi_app';
Si no mandas appName, el plugin usa el nombre del ejecutable actual.
4. Crea la configuración #
final config = UpsyncConfig(
manifestUrl: manifestUrl,
currentVersion: currentVersion,
currentBuildNumber: currentBuildNumber,
appName: appName,
);
Parámetros disponibles:
manifestUrlcurrentVersioncurrentBuildNumberappNamecheckIntervalrequestHeadersautoDownloadrequestTimeoutupdateSourceinstallMicrosoftStoreUpdates
Valores por defecto:
checkInterval: 30 minutosautoDownload:truerequestTimeout: 45 segundosupdateSource:UpsyncUpdateSource.manifestinstallMicrosoftStoreUpdates:true
5. Inicia el plugin #
Hazlo una vez cuando arranque tu app:
await Upsync.instance.start(config);
Ejemplo simple:
Future<void> initUpsync() async {
await Upsync.instance.start(
const UpsyncConfig(
manifestUrl: 'https://tu-dominio.com/windows/manifest.json',
currentVersion: '1.1.1',
currentBuildNumber: 113,
appName: 'mi_app',
),
);
}
Qué hace start():
- valida que estás en Windows;
- resuelve la ruta local de trabajo;
- recupera una actualización pendiente si ya existía;
- hace una comprobación inmediata;
- programa las comprobaciones periódicas.
6. Lee el estado #
Estado actual:
final state = Upsync.instance.state;
Stream de cambios:
Upsync.instance.states.listen((state) {
if (state.status == UpsyncStatus.downloading) {
print(state.progress);
}
if (state.isReadyToInstall) {
print('Hay una actualización lista');
}
});
Estados disponibles:
UpsyncStatus.idleUpsyncStatus.disabledUpsyncStatus.checkingUpsyncStatus.upToDateUpsyncStatus.updateAvailableUpsyncStatus.downloadingUpsyncStatus.downloadedUpsyncStatus.applyingUpsyncStatus.error
Helpers útiles:
final ready = Upsync.instance.state.isReadyToInstall;
final canApply = Upsync.instance.state.canApplyUpdate;
final showIndicator = Upsync.instance.state.showIndicator;
7. Fuerza una revisión manual #
final state = await Upsync.instance.checkNow();
Eso te sirve si quieres revisar actualizaciones al entrar al login, al abrir una pantalla o desde un botón.
8. Aplica la actualización #
Cuando la descarga ya esté lista:
await Upsync.instance.applyDownloadedUpdateAndRestart();
Ese método:
- lanza el helper nativo;
- cierra la app actual;
- aplica el paquete;
- vuelve a abrir la app.
9. Limpia una actualización pendiente #
Si por alguna razón necesitas borrar lo descargado:
await Upsync.instance.clearPendingUpdate();
Eso borra:
pending_update.json;- el paquete descargado pendiente, si existe.
Manifest #
El plugin acepta estas claves:
- versión:
versionoversionName - url:
url,downloadUrloexeUrl - build:
buildNumber,buildoversionCode - tipo:
packageTypeotype - hash:
sha256ochecksum - notas:
notesoreleaseNotes - tamaño:
fileSizeBytesosize
Ejemplo recomendado:
{
"version": "1.1.1",
"buildNumber": 113,
"url": "https://tu-dominio.com/releases/mi-app-windows.zip",
"packageType": "zip",
"sha256": "opcional_sha256",
"notes": "Notas opcionales",
"fileSizeBytes": 12345678
}
Campos obligatorios:
versionurl
Cómo decide si una versión es más nueva:
- si el manifest trae
buildNumbery tu config traecurrentBuildNumber, compara esos números; - si no, compara
versioncontracurrentVersion.
Paquetes soportados #
ZIP #
Es el caso más útil para Flutter Windows. El zip puede traer el contenido del release en la raíz:
mi_app.exe
flutter_windows.dll
data/
O dentro de una sola carpeta:
mi-app-windows/
mi_app.exe
flutter_windows.dll
data/
Ambos formatos funcionan.
EXE #
Si el manifest apunta a un .exe, el plugin intenta reemplazar el ejecutable
actual.
Dónde guarda los archivos #
Ruta base:
%LOCALAPPDATA%\<app>\updates\
Ahí guarda:
- subcarpetas por versión;
- el paquete descargado;
pending_update.json.
Si no envías appName, <app> sale del nombre del .exe.
Detalles útiles antes de usarlo #
manifestUrlno puede ir vacío.autoDownloadviene activado por defecto.- si
updateSourceesUpsyncUpdateSource.microsoftStore,manifestUrl,currentVersion,currentBuildNumber,requestHeaders,autoDownload,requestTimeout, las descargas locales,sha256y el helper ZIP/EXE no se usan. Microsoft Store controla la descarga y la instalación. - la comprobación de Microsoft Store solo funciona cuando la app corre con identidad de paquete, por ejemplo desde Store/MSIX.
- Microsoft Store limita la frecuencia de detección. En ese modo
upsyncmantiene el intervalo periódico en 30 minutos o más. - si ya había una descarga válida de una versión más nueva,
start()la recupera sin volver a descargar. - si el manifest trae
sha256, el archivo se valida antes de marcarse como listo. - hoy la API pública no expone un método aparte para descargar manualmente
después de marcar
autoDownload: false.
Actualizaciones con Microsoft Store #
Usa este modo cuando la app de Windows se distribuye por Microsoft Store o como un paquete MSIX asociado a Microsoft Store:
await Upsync.instance.start(
const UpsyncConfig.microsoftStore(),
);
Por defecto, si Microsoft Store informa una actualización, upsync pide a la
API oficial de Store que la descargue e instale. El sistema operativo puede
mostrar diálogos de Store para pedir permiso al usuario. Si solo quieres
detectar la actualización, desactiva la instalación automática de Store:
await Upsync.instance.start(
const UpsyncConfig.microsoftStore(
installMicrosoftStoreUpdates: false,
),
);
Cuando installMicrosoftStoreUpdates es false, checkNow() puede mover el
estado a UpsyncStatus.updateAvailable. Luego puedes llamar:
await Upsync.instance.applyDownloadedUpdateAndRestart();
En modo Microsoft Store este método delega la instalación a Store en lugar de usar un ZIP o EXE descargado localmente.
Ejemplo mínimo #
import 'package:flutter/material.dart';
import 'package:upsync/upsync.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Upsync.instance.start(
const UpsyncConfig(
manifestUrl: 'https://tu-dominio.com/windows/manifest.json',
currentVersion: '1.1.1',
currentBuildNumber: 113,
appName: 'mi_app',
),
);
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
Upsync.instance.states.listen((state) async {
if (state.isReadyToInstall) {
await Upsync.instance.applyDownloadedUpdateAndRestart();
}
});
}
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Upsync activo'),
),
),
);
}
}