FLUTTER ECOSYSTEM

Joshuaerinosho/offline_sync

एक पैकेज जिसका उद्देश्य डेटा को ऑफलाइन-पहले के अनुसार प्रबंधित और सिंक करना है, जिससे इंटरनेट कनेक्शन के बिना भी बिना किसी बाधा के काम करने में सक्षम होता है, और कनेक्शन बहाल होने पर स्वचालित सिंक करता है।

ऑफलाइन सिंक प्रोजेक्ट कवर
Stars
25
Forks
4
अंतिम पुश (UTC)
15 जुल॰ 2025
प्रोजेक्ट स्थिति
सक्रिय
Joshua Erinosho GitHub avatar
GITHUB User

Joshua Erinosho ↗

Tech Enthusiast

Abuja, Nigeria
भाषाएँDartRubySwiftObjective-C

इस रिपॉज़िटरी के पैकेज

उपयोग की गई निर्भरताएँ

निर्भरता सूची 15 आइटम

मूल README

यह अंग्रेज़ी मूल स्नैपशॉट है। नवीनतम सामग्री GitHub पर देखें।

README खोलें / बंद करें

OfflineSync

OfflineSync is a Flutter package that provides offline-first data management and synchronization. It ensures smooth functionality even without an internet connection and syncs data once connectivity is restored.

Features

  • Local data storage and retrieval
  • Automatic synchronization with server when online
  • Conflict resolution
  • Encryption of sensitive data
  • Batch syncing for improved performance
  • Error handling and retry mechanisms

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  offline_sync: ^1.0.0

Usage

Initialization

First, initialize the OfflineSync instance in your app:

import 'package:offline_sync/offline_sync.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final offlineSync = OfflineSync(
    config: OfflineSyncConfig(
      apiEndpoint: 'https://your-custom-api.com',
      // encryptionKey is optional and will be generated automatically if not provided
    ),
  );
  await offlineSync.initialize();
  runApp(MyApp());
}

Setting Custom API Endpoint

Set a custom endpoint for your specific server:

final offlineSync = OfflineSync();
offlineSync.setApiEndpoint('https://your-custom-api.com');

Saving Data

To save data locally and queue it for syncing:

final offlineSync = OfflineSync();
await offlineSync.saveLocalData('user_1', {
  'name': 'John Doe',
  'email': 'john@example.com',
  'age': 30,
});

Reading Data

To read locally stored data:

final userData = await offlineSync.readLocalData('user_1');
if (userData != null) {
  print('User name: ${userData['name']}');
} else {
  print('User not found');
}

Syncing with Server

The package automatically syncs data when an internet connection is available. However, you can manually trigger a sync:

try {
  await offlineSync.updateFromServer();
  print('Data updated from server successfully');
} catch (e) {
  print('Failed to update from server: $e');
}

Handling Authentication

Set the authentication token for API requests:

await offlineSync.setAuthToken('your_auth_token_here');

Advanced Usage:

Conflict Resolution

The package includes basic conflict resolution. You can customize this by extending the OfflineSync class:

class CustomOfflineSync extends OfflineSync {
  @override
  Future<Map<String, dynamic>> resolveConflict(
    String id,
    Map<String, dynamic> localData,
    Map<String, dynamic> serverData
  ) async {
    // Implement your custom conflict resolution strategy here
    // This example prefers local changes
    final resolvedData = Map<String, dynamic>.from(serverData);
    localData.forEach((key, value) {
      if (value != serverData[key]) {
        resolvedData[key] = value;
      }
    });
    return resolvedData;
  }
}

Batch Processing

The package processes sync queue in batches. You can adjust the batch size:

class CustomOfflineSync extends OfflineSync {
  @override
  int get batchSize => 100; // Default is 50
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Using with Flutter Provider

Wrap your app with the OfflineSyncProvider to make the sync instance and its status available throughout the widget tree:

final offlineSync = OfflineSync(config: OfflineSyncConfig(
  apiEndpoint: 'https://your-api.com',
  // encryptionKey is now optional
));
await offlineSync.initialize();

runApp(
  OfflineSyncProvider(
    offlineSync: offlineSync,
    child: MyApp(),
  ),
);

Then, anywhere in your widget tree, you can access the sync instance and status:

final offlineSync = OfflineSyncProvider.of(context);
ValueListenableBuilder<SyncStatus>(
  valueListenable: offlineSync.syncStatus,
  builder: (context, status, _) {
    // Show sync status in UI
    return Text('Sync status: $status');
  },
)

API Reference

OfflineSyncConfig
  • apiEndpoint (String, required): The server endpoint for syncing.
  • batchSize (int, default: 50): Number of items to sync per batch.
  • encryptionKey (String, optional): 32-character key for AES encryption. If not provided, a secure key is generated and stored automatically.
  • encryptionIV (IV, optional): Custom IV for encryption.
  • conflictResolver (callback, optional): Custom function for resolving data conflicts.
  • logger (callback, optional): Function for debug or error logging.
OfflineSync
  • OfflineSync({required OfflineSyncConfig config, ...}): Create a new instance with config and optional injected dependencies.
  • Future<void> initialize(): Initialize the database and connectivity.
  • Future<void> setAuthToken(String token): Set the auth token for API requests.
  • Future<void> saveLocalData(String id, Map<String, dynamic> data): Save data locally and queue for sync.
  • Future<Map<String, dynamic>?> readLocalData(String id): Read local data by ID.
  • Future<void> updateFromServer(): Manually trigger sync from server.
  • ValueNotifier<SyncStatus> syncStatus: Listen for sync status changes.
  • ValueNotifier<SyncErrorType?> lastError: Listen for error changes.
  • ValueNotifier<double> syncProgress: Listen for sync progress (0.0 to 1.0).

Migration Guide

From Singleton to Instance API
  • Before:
    final offlineSync = OfflineSync();
    await offlineSync.initialize();
    offlineSync.setApiEndpoint('https://api.com');
    
  • After:
    final offlineSync = OfflineSync(
      config: OfflineSyncConfig(
        apiEndpoint: 'https://api.com',
        // encryptionKey is now optional
      ),
    );
    await offlineSync.initialize();
    
  • Use the new OfflineSyncProvider to expose the instance to your widget tree.
  • Set all configuration options via OfflineSyncConfig instead of setters.