diff --git a/CHANGELOG.md b/CHANGELOG.md index 17223fa..9227858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +* Update `device_info_plus` and `package_info_plus` to the minimum versions with iOS/macOS Swift Package Manager support. +* Fall back to platform OS metadata when device metadata collection fails. +* Ignore non-Aptabase SharedPreferences entries when loading queued events. + ## 0.4.1 * Change "SystemChannels.lifecycle" to "AppLifecycleListener" diff --git a/lib/storage_manager_shared_prefs.dart b/lib/storage_manager_shared_prefs.dart index 40ad1c7..df7ccbf 100644 --- a/lib/storage_manager_shared_prefs.dart +++ b/lib/storage_manager_shared_prefs.dart @@ -2,6 +2,8 @@ import "package:aptabase_flutter/storage_manager.dart"; import "package:shared_preferences/shared_preferences.dart"; class StorageManagerSharedPrefs extends StorageManager { + static const _eventKeyPrefix = "aptabase_"; + final _events = {}; @override @@ -9,8 +11,10 @@ class StorageManagerSharedPrefs extends StorageManager { final sharedPrefs = await SharedPreferences.getInstance(); final keys = sharedPrefs.getKeys(); for (final key in keys) { - final value = sharedPrefs.getString(key); - if (value != null) _events[key] = value; + if (!key.startsWith(_eventKeyPrefix)) continue; + + final value = sharedPrefs.get(key); + if (value is String) _events[key] = value; } return super.init(); diff --git a/lib/sys_info.dart b/lib/sys_info.dart index e2d65bf..88f76c0 100644 --- a/lib/sys_info.dart +++ b/lib/sys_info.dart @@ -48,9 +48,21 @@ class SystemInfo { } /// Returns info (name and version) of the operating system. - static Future<({String name, String version})> _getOsInfo() async { - final deviceInfo = DeviceInfoPlugin(); + static Future<({String name, String version})> _getOsInfo({ + Future<({String name, String version})> Function(DeviceInfoPlugin)? + resolveOsInfo, + ({String name, String version}) Function()? fallbackOsInfo, + }) async { + try { + return await (resolveOsInfo ?? _resolveOsInfo)(DeviceInfoPlugin()); + } catch (_) { + return (fallbackOsInfo ?? _platformFallbackOsInfo)(); + } + } + static Future<({String name, String version})> _resolveOsInfo( + DeviceInfoPlugin deviceInfo, + ) async { if (kIsWeb) { final info = await deviceInfo.webBrowserInfo; @@ -108,4 +120,39 @@ class SystemInfo { version: Platform.operatingSystemVersion, ); } + + static ({String name, String version}) _platformFallbackOsInfo() { + if (Platform.isAndroid) { + return (name: _kAndroidOsName, version: Platform.operatingSystemVersion); + } + + if (Platform.isIOS) { + return (name: _kIPhoneOsName, version: Platform.operatingSystemVersion); + } + + if (Platform.isMacOS) { + return (name: _kMacOsName, version: Platform.operatingSystemVersion); + } + + if (Platform.isWindows) { + return (name: _kWindowsOsName, version: Platform.operatingSystemVersion); + } + + return ( + name: Platform.operatingSystem, + version: Platform.operatingSystemVersion, + ); + } + + @visibleForTesting + static Future<({String name, String version})> getOsInfoForTesting({ + Future<({String name, String version})> Function(DeviceInfoPlugin)? + resolveOsInfo, + ({String name, String version}) Function()? fallbackOsInfo, + }) { + return _getOsInfo( + resolveOsInfo: resolveOsInfo, + fallbackOsInfo: fallbackOsInfo, + ); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 895ee98..ad6b735 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,14 +6,14 @@ repository: https://github.com/aptabase/aptabase_flutter issue_tracker: https://github.com/aptabase/aptabase_flutter/issues environment: - sdk: '>=3.2.0 <4.0.0' - flutter: ">=1.17.0" + sdk: '>=3.3.0 <4.0.0' + flutter: ">=3.19.0" dependencies: flutter: sdk: flutter - package_info_plus: ^8.0.0 - device_info_plus: ^10.1.0 + package_info_plus: ^8.3.1 + device_info_plus: ">=11.1.1 <11.2.0" universal_io: ^2.2.2 shared_preferences: ^2.3.3 diff --git a/test/storage_manager_shared_prefs_test.dart b/test/storage_manager_shared_prefs_test.dart new file mode 100644 index 0000000..107431a --- /dev/null +++ b/test/storage_manager_shared_prefs_test.dart @@ -0,0 +1,22 @@ +import "package:aptabase_flutter/storage_manager_shared_prefs.dart"; +import "package:flutter_test/flutter_test.dart"; +import "package:shared_preferences/shared_preferences.dart"; + +void main() { + test("loads only Aptabase string events from shared preferences", () async { + SharedPreferences.setMockInitialValues({ + "flutter.analytics_enabled": true, + "aptabase_1": "event-one", + "aptabase_2": 2, + }); + + final storage = StorageManagerSharedPrefs(); + await storage.init(); + + final items = (await storage.getItems(10)).toList(); + + expect(items, hasLength(1)); + expect(items.single.key, "aptabase_1"); + expect(items.single.value, "event-one"); + }); +} diff --git a/test/sys_info_test.dart b/test/sys_info_test.dart new file mode 100644 index 0000000..a92ca9f --- /dev/null +++ b/test/sys_info_test.dart @@ -0,0 +1,14 @@ +import "package:aptabase_flutter/sys_info.dart"; +import "package:flutter_test/flutter_test.dart"; + +void main() { + test("falls back to platform OS info when device metadata fails", () async { + final osInfo = await SystemInfo.getOsInfoForTesting( + resolveOsInfo: (_) => throw StateError("device info unavailable"), + fallbackOsInfo: () => (name: "Windows", version: "10.0.26200"), + ); + + expect(osInfo.name, "Windows"); + expect(osInfo.version, "10.0.26200"); + }); +}