upsync 0.0.1+3
upsync: ^0.0.1+3 copied to clipboard
Plugin Flutter para descargar y aplicar actualizaciones de Windows en segundo plano.
upsync #
Menu / Menú #
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;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.0.1+2
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:
manifestUrlcurrentVersioncurrentBuildNumberappNamecheckIntervalrequestHeadersautoDownloadrequestTimeout
Default values:
checkInterval: 30 minutesautoDownload:truerequestTimeout: 45 seconds
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 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 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.
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; - 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.0.1+2
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:
manifestUrlcurrentVersioncurrentBuildNumberappNamecheckIntervalrequestHeadersautoDownloadrequestTimeout
Valores por defecto:
checkInterval: 30 minutosautoDownload:truerequestTimeout: 45 segundos
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 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 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.
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'),
),
),
);
}
}