Skip to content

Commit

Permalink
Prevent data loss if shared_preferences.json is corrupted
Browse files Browse the repository at this point in the history
  • Loading branch information
Gold872 committed Oct 31, 2023
1 parent 89ca2f5 commit 97aaf17
Showing 1 changed file with 53 additions and 2 deletions.
55 changes: 53 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import 'dart:io';
import 'dart:ui';

import 'package:elastic_dashboard/pages/dashboard_page.dart';
import 'package:elastic_dashboard/services/field_images.dart';
import 'package:elastic_dashboard/services/globals.dart';
import 'package:elastic_dashboard/services/nt4_connection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();

final PackageInfo packageInfo = await PackageInfo.fromPlatform();
final SharedPreferences preferences = await SharedPreferences.getInstance();

final String appFolderPath = (await getApplicationSupportDirectory()).path;

// Prevents data loss if shared_preferences.json gets corrupted
// More info and original implementation: https://github.com/flutter/flutter/issues/89211#issuecomment-915096452
SharedPreferences preferences;
try {
preferences = await SharedPreferences.getInstance();

// Store a copy of user's preferences on the disk
await _backupPreferences(appFolderPath);
} catch (error) {
// Remove broken preferences files and restore previous settings
await _restorePreferencesFromBackup(appFolderPath);
preferences = await SharedPreferences.getInstance();
}

await windowManager.ensureInitialized();

Expand Down Expand Up @@ -53,6 +69,41 @@ void main() async {
runApp(Elastic(version: packageInfo.version, preferences: preferences));
}

/// Makes a backup copy of the current shared preferences file.
Future<void> _backupPreferences(String appFolderPath) async {
try {
final String original = '$appFolderPath\\shared_preferences.json';
final String backup = '$appFolderPath\\shared_preferences_backup.json';

if (await File(backup).exists()) await File(backup).delete(recursive: true);
await File(original).copy(backup);
} catch (_) {
/* Do nothing */
}
}

/// Removes current version of shared_preferences file and restores previous
/// user settings from a backup file (if it exists).
Future<void> _restorePreferencesFromBackup(String appFolderPath) async {
try {
final String original = '$appFolderPath\\shared_preferences.json';
final String backup = '$appFolderPath\\shared_preferences_backup.json';

await File(original).delete(recursive: true);

if (await File(backup).exists()) {
// Check if current backup copy is not broken by looking for letters and "
// symbol in it to replace it as an original Settings file
final String preferences = await File(backup).readAsString();
if (preferences.contains('"') && preferences.contains(RegExp('[A-z]'))) {
await File(backup).copy(original);
}
}
} catch (_) {
/* Do nothing */
}
}

class Elastic extends StatefulWidget {
final SharedPreferences preferences;
final String version;
Expand Down

0 comments on commit 97aaf17

Please sign in to comment.