flutter_cache_manager

repository·develop·Indexed 21 days ago

https://github.com/baseflow/flutter_cache_manager

A library for downloading and caching files in a Flutter app's cache directory. It supports HTTP Cache-Control headers for efficient retrieval, provides specialized image resizing via ImageCacheManager, and includes a Firebase-backed implementation through FirebaseCacheManager. Key features include support for custom configurations via Config, manual cache management (putFile, removeFile, emptyCache), and a DefaultCacheManager singleton for quick setup.

Tokens
6.3K
Snippets
27
Records
32
Agent score
74%

What's inside flutter_cache_manager

  1. How cache storage and expiration work

    develop

    Storage

    By default, files are stored in the app's temporary directory, meaning the OS may delete them at any time. Metadata about the files is stored in a database:

    • Android, iOS, macOS: Uses sqflite.
    • Other platforms: Uses a plain JSON file. The database filename is derived from the CacheManager's key.

    Updates

    The manager uses the HTTP Cache-Control header and eTag to determine if a file is still valid. When calling getSingleFile or getFileStream, the manager checks if the cached file is outdated. If it is, the manager updates the file and returns the new version via the stream.

    Removal

    Files are removed based on two criteria:

    1. maxNrOfCacheObjects: When the limit is reached, files are deleted based on their last use (LRU).
    2. stalePeriod: Files that haven't been used for longer than this duration are deleted during continuous cache cleaning.
  2. Customize iOS launch screen assets

    develop

    To change the launch screen image for the iOS version of your Flutter application, you can use one of two methods:

    1. Direct File Replacement: Replace the existing image files located in the ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.
    2. Xcode Interface:
      • Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
      • In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
      • Drag and drop your desired images directly into the asset catalog.
    open ios/Runner.xcworkspace
  3. Customize CacheManager with Config

    develop

    You can create a custom CacheManager by providing a Config object.

    Important: Do not create more than one CacheManager instance with the same key, as they will conflict with each other. It is recommended to manage your custom manager as a Singleton or provide it via a dependency injection tool like Provider.

    The Config constructor requires a key and accepts several optional parameters:

    • stalePeriod: A Duration defining how long a file is considered valid.
    • maxNrOfCacheObjects: The maximum number of objects to keep in the cache.
    • repo: The cache information repository (e.g., JsonCacheInfoRepository).
    • fileSystem: The file system implementation (e.g., IOFileSystem).
    • fileService: The service used to fetch files (e.g., HttpFileService).
    class CustomCacheManager {
      static const key = 'customCacheKey';
      static CacheManager instance = CacheManager(
        Config(
          key,
          stalePeriod: const Duration(days: 7),
          maxNrOfCacheObjects: 20,
          repo: JsonCacheInfoRepository(databaseName: key),
          fileSystem: IOFileSystem(key),
          fileService: HttpFileService(),
        ),
      );
    }
  4. Basic usage of flutter_cache_manager

    develop

    You can use DefaultCacheManager to download and retrieve files from the app's cache directory. The manager uses HTTP Cache-Control headers to manage file freshness and efficiency.

    Common methods include:

    • getSingleFile(url): The easiest way to get a single file. Returns the file from cache or downloads it if missing.
    • getFileStream(url): Returns a stream where the first event is the cached file and subsequent events are the newly downloaded file if an update occurred.
    • getFileStream(url, withProgress: true): Similar to getFileStream, but also emits DownloadProgress events when the file is not in the cache.
    • downloadFile(url): Directly downloads the file from the web without checking the cache first.
    • getFileFromCache(url): Retrieves the file only if it exists in the cache; returns nothing if it is missing.
    • putFile(...): Manually adds a new file to the cache without downloading it.
    • removeFile(url): Removes a specific file from the cache.
    • emptyCache(): Removes all files from the cache.
    // Get a single file
    var file = await DefaultCacheManager().getSingleFile(url);
    
    // Get a stream of files (cached then potentially updated)
    var stream = DefaultCacheManager().getFileStream(url);
    
    // Get a stream with download progress
    var progressStream = DefaultCacheManager().getFileStream(url, withProgress: true);
  5. Implement a custom FileService

    develop

    The FileService abstract class defines the interface for fetching files. While HttpFileService is the default implementation for web-based fetching, you can implement your own FileService to fetch files from alternative sources such as local storage or other applications.

    To implement a custom service, you must provide an implementation for the get method, which returns a FileServiceResponse.

    class MyCustomFileService extends FileService {
      @override
      Future<FileServiceResponse> get(String url, {Map<String, String>? headers}) async {
        // Implement custom fetching logic here
        // Return a class that implements FileServiceResponse
      }
    }
  6. Understand the CacheObject structure

    develop

    A CacheObject represents a single file stored in the cache along with its associated metadata. This metadata is used to manage cache expiration, identification, and cleanup.

    Key properties include:

    • url: The original URL used to download the file.
    • key: The unique identifier for the object (defaults to the url if not provided).
    • relativePath: The location of the file within the cache storage.
    • validTill: The timestamp after which the cached item is considered invalid.
    • eTag: The server-provided ETag used for cache validation.
    • touched: The timestamp of the last time the file was accessed/used.
    • length: The size of the cached file in bytes.
  7. Initialize CacheManager with Config

    develop

    To use CacheManager, create an instance by passing a Config object. It is recommended to use a singleton pattern for your CacheManager instance. The Config object determines how files are stored, the cache's lifecycle (stale period and max size), and how files are downloaded via the fileService.

    Key behaviors:

    • Files are removed if they exceed the stalePeriod or if the cache exceeds maxNrOfCacheObjects.
    • The _cacheKey in your config is used for the underlying SQLite database and should be unique.
    // Assuming Config is already defined and imported
    final cacheManager = CacheManager(Config(
      // configuration parameters
    ));
  8. Use ImageCacheManager for resized images

    develop

    By using the ImageCacheManager mixin (which is included in DefaultCacheManager), you gain access to the getImageFile method. This method allows you to request an image at specific dimensions. The manager will resize the image, cache the resized version, and maintain the original aspect ratio. The original image is also cached to allow for future resizing with different parameters.

    getImageFile signature:

    Stream<FileResponse> getImageFile(
      String url, {
      String? key,
      Map<String, String>? headers,
      bool withProgress = false,
      int? maxHeight,
      int? maxWidth,
    })```
    
    ```dart
    // Example usage of getImageFile (available via DefaultCacheManager)
    var imageStream = DefaultCacheManager().getImageFile(
      url,
      maxHeight: 500,
      maxWidth: 500,
    );
  9. Breaking changes in v2

    develop

    If you are migrating from v1 to v2, note the following changes:

    • Implementation: You no longer need to extend BaseCacheManager. BaseCacheManager is now an interface, and you should use the CacheManager class directly.
    • Configuration: The constructor now requires a Config object.
    • FileSystem: Instead of using a simple dictionary for storage, the system now uses a FileSystem object, providing more flexibility in where files are stored.