Skip to content

Commit fcde2f7

Browse files
committed
chore: Add auto_updater_macos package
1 parent 69edf82 commit fcde2f7

23 files changed

+594
-136
lines changed

packages/auto_updater/example/lib/pages/home.dart

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:auto_updater/auto_updater.dart';
22
import 'package:bot_toast/bot_toast.dart';
3+
import 'package:flutter/foundation.dart';
34
import 'package:flutter/material.dart';
45
import 'package:preference_list/preference_list.dart';
56

@@ -10,16 +11,23 @@ class HomePage extends StatefulWidget {
1011
State<HomePage> createState() => _HomePageState();
1112
}
1213

13-
class _HomePageState extends State<HomePage> {
14+
class _HomePageState extends State<HomePage> with UpdaterListener {
1415
final String _feedURL = 'http://localhost:5002/appcast.xml';
1516

1617
bool _isFeedURLSetted = false;
1718

1819
@override
1920
void initState() {
21+
autoUpdater.addListener(this);
2022
super.initState();
2123
}
2224

25+
@override
26+
void dispose() {
27+
autoUpdater.removeListener(this);
28+
super.dispose();
29+
}
30+
2331
Future<void> _handleClickSetFeedURL() async {
2432
await autoUpdater.setFeedURL(_feedURL);
2533
_isFeedURLSetted = true;
@@ -87,4 +95,46 @@ class _HomePageState extends State<HomePage> {
8795
body: _buildBody(context),
8896
);
8997
}
98+
99+
@override
100+
void onUpdaterError(UpdaterError? error) {
101+
if (kDebugMode) {
102+
print('onUpdaterError: $error');
103+
}
104+
}
105+
106+
@override
107+
void onUpdaterCheckingForUpdate(Appcast? appcast) {
108+
if (kDebugMode) {
109+
print('onUpdaterCheckingForUpdate: ${appcast?.toJson()}');
110+
}
111+
}
112+
113+
@override
114+
void onUpdaterUpdateAvailable(AppcastItem? item) {
115+
if (kDebugMode) {
116+
print('onUpdaterUpdateAvailable: ${item?.toJson()}');
117+
}
118+
}
119+
120+
@override
121+
void onUpdaterUpdateNotAvailable(UpdaterError? error) {
122+
if (kDebugMode) {
123+
print('onUpdaterUpdateNotAvailable: $error');
124+
}
125+
}
126+
127+
@override
128+
void onUpdaterUpdateDownloaded(AppcastItem? item) {
129+
if (kDebugMode) {
130+
print('onUpdaterUpdateDownloaded: ${item?.toJson()}');
131+
}
132+
}
133+
134+
@override
135+
void onUpdaterBeforeQuitForUpdate(AppcastItem? item) {
136+
if (kDebugMode) {
137+
print('onUpdaterBeforeQuitForUpdate: ${item?.toJson()}');
138+
}
139+
}
90140
}

packages/auto_updater/example/macos/Flutter/GeneratedPluginRegistrant.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
import FlutterMacOS
66
import Foundation
77

8-
import auto_updater
8+
import auto_updater_macos
99
import screen_retriever
1010
import window_manager
1111

1212
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
13-
AutoUpdaterPlugin.register(with: registry.registrar(forPlugin: "AutoUpdaterPlugin"))
13+
AutoUpdaterMacosPlugin.register(with: registry.registrar(forPlugin: "AutoUpdaterMacosPlugin"))
1414
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
1515
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
1616
}

packages/auto_updater/example/macos/Podfile.lock

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
PODS:
2-
- auto_updater (0.0.1):
2+
- auto_updater_macos (0.0.1):
33
- FlutterMacOS
44
- Sparkle
55
- FlutterMacOS (1.0.0)
66
- screen_retriever (0.0.1):
77
- FlutterMacOS
8-
- Sparkle (2.0.0)
8+
- Sparkle (2.5.2)
99
- window_manager (0.2.0):
1010
- FlutterMacOS
1111

1212
DEPENDENCIES:
13-
- auto_updater (from `Flutter/ephemeral/.symlinks/plugins/auto_updater/macos`)
13+
- auto_updater_macos (from `Flutter/ephemeral/.symlinks/plugins/auto_updater_macos/macos`)
1414
- FlutterMacOS (from `Flutter/ephemeral`)
1515
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
1616
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
@@ -20,8 +20,8 @@ SPEC REPOS:
2020
- Sparkle
2121

2222
EXTERNAL SOURCES:
23-
auto_updater:
24-
:path: Flutter/ephemeral/.symlinks/plugins/auto_updater/macos
23+
auto_updater_macos:
24+
:path: Flutter/ephemeral/.symlinks/plugins/auto_updater_macos/macos
2525
FlutterMacOS:
2626
:path: Flutter/ephemeral
2727
screen_retriever:
@@ -30,10 +30,10 @@ EXTERNAL SOURCES:
3030
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
3131

3232
SPEC CHECKSUMS:
33-
auto_updater: d3c03e9e5f2a00ec78572d9f7473cb8c9a6c0273
33+
auto_updater_macos: 3e3462c418fe4e731917eacd8d28eef7af84086d
3434
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
3535
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
36-
Sparkle: 128c668ddd0780beb08576ce18460d2a37f64f9f
36+
Sparkle: 0e335e5c704ac28dbea18cc0383e15a3927c28dc
3737
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
3838

3939
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
library auto_updater;
2+
3+
export 'src/appcast.dart';
14
export 'src/auto_updater.dart';
5+
export 'src/updater_error.dart';
6+
export 'src/updater_listener.dart';
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import 'package:json_annotation/json_annotation.dart';
2+
3+
part 'appcast.g.dart';
4+
5+
@JsonSerializable()
6+
class Appcast {
7+
const Appcast({
8+
required this.items,
9+
});
10+
11+
factory Appcast.fromJson(Map<String, dynamic> json) {
12+
json['items'] = (json['items'] as List)
13+
.map((e) => (e as Map).cast<String, dynamic>())
14+
.toList();
15+
return _$AppcastFromJson(json);
16+
}
17+
18+
final List<AppcastItem> items;
19+
20+
Map<String, dynamic> toJson() => _$AppcastToJson(this);
21+
}
22+
23+
@JsonSerializable()
24+
class AppcastItem {
25+
const AppcastItem({
26+
this.versionString,
27+
this.displayVersionString,
28+
this.fileURL,
29+
this.contentLength,
30+
this.infoURL,
31+
this.title,
32+
this.dateString,
33+
this.releaseNotesURL,
34+
this.itemDescription,
35+
this.itemDescriptionFormat,
36+
this.fullReleaseNotesURL,
37+
this.minimumSystemVersion,
38+
this.minimumOperatingSystemVersionIsOK,
39+
this.maximumSystemVersion,
40+
this.maximumOperatingSystemVersionIsOK,
41+
this.channel,
42+
});
43+
44+
factory AppcastItem.fromJson(Map<String, dynamic> json) =>
45+
_$AppcastItemFromJson(json);
46+
47+
final String? versionString;
48+
final String? displayVersionString;
49+
final String? fileURL;
50+
final int? contentLength;
51+
final String? infoURL;
52+
final String? title;
53+
final String? dateString;
54+
final String? releaseNotesURL;
55+
final String? itemDescription;
56+
final String? itemDescriptionFormat;
57+
final String? fullReleaseNotesURL;
58+
final String? minimumSystemVersion;
59+
final bool? minimumOperatingSystemVersionIsOK;
60+
final String? maximumSystemVersion;
61+
final bool? maximumOperatingSystemVersionIsOK;
62+
final String? channel;
63+
64+
Map<String, dynamic> toJson() => _$AppcastItemToJson(this);
65+
}

packages/auto_updater/lib/src/appcast.g.dart

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/auto_updater/lib/src/auto_updater.dart

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,101 @@
11
import 'dart:async';
22

3-
import 'package:flutter/services.dart';
3+
import 'package:auto_updater/src/appcast.dart';
4+
import 'package:auto_updater/src/updater_error.dart';
5+
import 'package:auto_updater/src/updater_listener.dart';
6+
import 'package:auto_updater_platform_interface/auto_updater_platform_interface.dart';
47

58
class AutoUpdater {
69
AutoUpdater._() {
7-
_channel.setMethodCallHandler(_methodCallHandler);
10+
_platform.sparkleEvents.listen(_handleSparkleEvents);
811
}
912

1013
/// The shared instance of [AutoUpdater].
1114
static final AutoUpdater instance = AutoUpdater._();
1215

13-
/// Event stream for sparkle/winsparkle events
14-
final _eventController = StreamController<String>.broadcast();
15-
Stream<String> get sparkleEvents => _eventController.stream;
16+
AutoUpdaterPlatform get _platform => AutoUpdaterPlatform.instance;
1617

17-
final MethodChannel _channel = const MethodChannel('auto_updater');
18+
final List<UpdaterListener> _listeners = [];
1819

19-
Future<void> _methodCallHandler(MethodCall call) async {
20-
if (call.method != 'onEvent') throw UnimplementedError();
21-
if (!call.arguments.containsKey('eventName')) throw UnimplementedError();
20+
void _handleSparkleEvents(event) {
21+
UpdaterError? updaterError;
22+
Appcast? appcast;
23+
AppcastItem? appcastItem;
2224

23-
_eventController.add(call.arguments['eventName']);
25+
String type = event['type'] as String;
26+
Map<Object?, Object?>? data;
27+
if (event['data'] != null) {
28+
data = event['data'] as Map;
29+
30+
if (data['error'] != null) {
31+
updaterError = UpdaterError(
32+
data['error'].toString(),
33+
);
34+
}
35+
if (data['appcast'] != null) {
36+
appcast = Appcast.fromJson(
37+
Map<String, dynamic>.from(
38+
(data['appcast'] as Map).cast<String, dynamic>(),
39+
),
40+
);
41+
}
42+
if (data['appcastItem'] != null) {
43+
appcastItem = AppcastItem.fromJson(
44+
Map<String, dynamic>.from(
45+
(data['appcastItem'] as Map).cast<String, dynamic>(),
46+
),
47+
);
48+
}
49+
}
50+
for (var listener in _listeners) {
51+
switch (type) {
52+
case 'error':
53+
listener.onUpdaterError(updaterError!);
54+
break;
55+
case 'checking-for-update':
56+
listener.onUpdaterCheckingForUpdate(appcast);
57+
break;
58+
case 'update-available':
59+
listener.onUpdaterUpdateAvailable(appcastItem);
60+
break;
61+
case 'update-not-available':
62+
listener.onUpdaterUpdateNotAvailable(updaterError);
63+
break;
64+
case 'update-downloaded':
65+
listener.onUpdaterUpdateDownloaded(appcastItem);
66+
break;
67+
case 'before-quit-for-update':
68+
listener.onUpdaterBeforeQuitForUpdate(appcastItem);
69+
break;
70+
}
71+
}
72+
}
73+
74+
/// Adds a listener to the auto updater.
75+
void addListener(UpdaterListener listener) {
76+
_listeners.add(listener);
77+
}
78+
79+
/// Removes a listener from the auto updater.
80+
void removeListener(UpdaterListener listener) {
81+
_listeners.remove(listener);
2482
}
2583

2684
/// Sets the url and initialize the auto updater.
27-
Future<void> setFeedURL(String feedUrl) async {
28-
final Map<String, dynamic> arguments = {
29-
'feedURL': feedUrl,
30-
};
31-
await _channel.invokeMethod('setFeedURL', arguments);
85+
Future<void> setFeedURL(String feedUrl) {
86+
return _platform.setFeedURL(feedUrl);
3287
}
3388

3489
/// Asks the server whether there is an update. You must call setFeedURL before using this API.
35-
Future<void> checkForUpdates({bool? inBackground}) async {
36-
final Map<String, dynamic> arguments = {
37-
'inBackground': inBackground ?? false,
38-
};
39-
await _channel.invokeMethod('checkForUpdates', arguments);
90+
Future<void> checkForUpdates({bool? inBackground}) {
91+
return _platform.checkForUpdates(
92+
inBackground: inBackground,
93+
);
4094
}
4195

4296
/// Sets the auto update check interval, default 86400, minimum 3600, 0 to disable update
43-
Future<void> setScheduledCheckInterval(int interval) async {
44-
final Map<String, dynamic> arguments = {
45-
'interval': interval,
46-
};
47-
await _channel.invokeMethod('setScheduledCheckInterval', arguments);
97+
Future<void> setScheduledCheckInterval(int interval) {
98+
return _platform.setScheduledCheckInterval(interval);
4899
}
49100
}
50101

0 commit comments

Comments
 (0)