cross_cache 0.0.11 copy "cross_cache: ^0.0.11" to clipboard
cross_cache: ^0.0.11 copied to clipboard

Cross-platform cache manager for Flutter using IndexedDB for web, file system for mobile and desktop, and Dio for network requests. #cache #indexeddb #dio

Cross Cache 💾 #

Pub Version melos

A simple cross-platform caching library for Flutter, primarily designed for caching network resources like images.

✨ Features #

  • 💾 Cross-Platform Caching: Automatically uses the appropriate storage mechanism for Web and IO platforms.
  • 🌐 Versatile Fetching: Downloads and caches resources from various sources:
    • Network URLs (http, https, blob)
    • Flutter asset paths (assets/...)
    • Data URIs (data:...)
    • Local file paths (IO platforms only)
    • Base64 encoded strings
  • 🤝 Dio Integration: Uses dio for network requests (instance can be provided).
  • 🖼️ Flutter ImageProvider: Includes CachedNetworkImage, a drop-in replacement for NetworkImage that uses the cache.
  • ⚙️ Standard Cache API: Provides basic get, set, contains, delete, and updateKey methods for direct cache interaction.

🚀 Installation #

Add this package to your pubspec.yaml:

dependencies:
  cross_cache: ^ # Use the latest version

Then run flutter pub get.

📖 Usage #

Initialization #

Create an instance of CrossCache. You can optionally provide your own configured Dio instance.

import 'package:cross_cache/cross_cache.dart';
import 'package:dio/dio.dart';

// Basic initialization
final cache = CrossCache();

// Or with a custom Dio instance
final dio = Dio(/* your custom options */);
final customCache = CrossCache(dio: dio);

// Remember to dispose when done (e.g., in your State's dispose method)
// cache.dispose();

Downloading and Caching (downloadAndSave) #

This is the primary method for fetching resources from various sources and caching them automatically. It returns the Uint8List data. If the resource is already cached, it returns the cached data directly.

Future<void> loadImageData(String imageUrl) async {
  try {
    final Uint8List imageData = await cache.downloadAndSave(
      imageUrl,
      headers: {'Authorization': 'Bearer YOUR_TOKEN'}, // Optional headers
      onReceiveProgress: (cumulative, total) {
        print('Download progress: ${cumulative / total * 100}%'); // Optional progress
      },
    );
    // Use imageData (e.g., display with Image.memory)
    print('Image loaded, ${imageData.lengthInBytes} bytes');
  } catch (e) {
    print('Error loading image: $e');
  }
}

// Examples of different sources:
// await loadImageData('https://example.com/image.jpg');
// await loadImageData('assets/my_icon.png');
// await loadImageData('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...');
// await loadImageData('/path/to/local/file.jpg'); // IO only
// await loadImageData('iVBORw0KGgoAAAANSUhEUgAAAAUA...'); // Base64 string

Using CachedNetworkImage (Flutter) #

Use CachedNetworkImage directly with Flutter's Image widget as a replacement for NetworkImage. It automatically uses your CrossCache instance.

import 'package:flutter/material.dart';
import 'package:cross_cache/cross_cache.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final _cache = CrossCache(); // Create an instance

  @override
  void dispose() {
    _cache.dispose(); // Dispose the cache
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Image(
      image: CachedNetworkImage(
        'https://example.com/image.jpg',
        _cache, // Pass the cache instance
        headers: {'Authorization': 'Bearer YOUR_TOKEN'}, // Optional headers
      ),
      loadingBuilder: (context, child, loadingProgress) {
        if (loadingProgress == null) return child;
        return Center(
          child: CircularProgressIndicator(
            value: loadingProgress.expectedTotalBytes != null
                ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
                : null,
          ),
        );
      },
      errorBuilder: (context, error, stackTrace) => Icon(Icons.error),
    );
  }
}

Direct Cache Access #

You can interact with the cache directly if needed, though downloadAndSave handles most common cases.

// Check if an item exists
bool exists = await cache.contains('my_unique_key');

// Manually add data
Uint8List myData = Uint8List.fromList([1, 2, 3]);
await cache.set('my_unique_key', myData);

// Retrieve data
try {
  Uint8List cachedData = await cache.get('my_unique_key');
  // Use cachedData
} catch (e) {
  print('Key not found or error: $e');
}

// Delete data
await cache.delete('my_unique_key');

// Rename cache key
// await cache.updateKey('old_key', 'new_key');

🤔 How It Works #

  • Web: Uses the idb_shim package to store Uint8List data in an IndexedDB object store named data within a database called cross_cache_db. The cache key is used directly as the IndexedDB key.
  • IO: Uses the path_provider package to get the application's cache directory. It creates a cross_cache subdirectory. The provided cache key is SHA256 hashed to create a unique filename, and the Uint8List data is written to that file.

🚧 Future Work #

  • Better error handling.
  • Cache management features like manual/automatic purging.
  • Cancellation support for downloads in progress.
  • Option to set maximum cache size or item count.
  • Caching strategy (LRU, MRU, FIFO etc.)

🤝 Contributing #

Contributions are welcome! Please see the main project's Contributing Guide.

📜 License #

Licensed under the MIT License. See the LICENSE file for details.

2
likes
150
points
2.75k
downloads

Publisher

verified publisherflyer.chat

Weekly Downloads

Cross-platform cache manager for Flutter using IndexedDB for web, file system for mobile and desktop, and Dio for network requests. #cache #indexeddb #dio

Homepage
Repository (GitHub)
Contributing

Documentation

API reference

License

MIT (license)

Dependencies

cross_file, crypto, dio, flutter, idb_shim, path_provider

More

Packages that depend on cross_cache