Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cache the response of API calls in Flutter?

Tags:

flutter

I am working in Flutter App to get the items from API. I want to cache the API response for 12 hours. Every 12 hours the response will be changed. Once the 12 hours completed then I need to fetch it from Internet. I used the below code to get it from internet.

Future<List<Playlist>> fetchPlaylistByChannelId({String channelId}) async {
Map<String, String> parameters = {
  'part': 'snippet,contentDetails',
  'channelId': channelId,
  'maxResults': '10',
  'key': API_KEY,
};
Uri uri = Uri.https(
  _baseUrl,
  '/youtube/v3/playlists',
  parameters,
);
Map<String, String> headers = {
  HttpHeaders.contentTypeHeader: 'application/json',
};

// Get Playlist details
var response = await http.get(uri, headers: headers);
if (response.statusCode == 200) {
  var data = json.decode(response.body);
  List<dynamic> playListJson = data['items'];

  // Fetch all play list
  List<Playlist> playLists = [];
  playListJson.forEach(
    (json) => playLists.add(
      Playlist.fromMap(
        json["id"],
        json["snippet"],
        json["contentDetails"],
      ),
    ),
  );
  return playLists;
} else {
  throw json.decode(response.body)['error']['message'];
}   }

Please help me out this.

like image 508
Philip Jebaraj Avatar asked Feb 07 '20 06:02

Philip Jebaraj


2 Answers

Include flutter_cache_manager in pubspec.yaml.

Now define a cache manager

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

// Custom Implementation of CacheManager
// by extending the BaseCacheManager abstract class
class MyCacheManager extends BaseCacheManager {
  static const key = "customCache";

  static MyCacheManager _instance;

  // singleton implementation 
  // for the custom cache manager
  factory MyCacheManager() {
    if (_instance == null) {
      _instance = new MyCacheManager._();
    }
    return _instance;
  }

  // pass the default setting values to the base class
  // link the custom handler to handle HTTP calls 
  // via the custom cache manager
  MyCacheManager._()
      : super(key,
            maxAgeCacheObject: Duration(hours: 12),
            maxNrOfCacheObjects: 200,
            fileFetcher: _myHttpGetter);

  @override
  Future<String> getFilePath() async {
    var directory = await getTemporaryDirectory();
    return path.join(directory.path, key);
  }

  static Future<FileFetcherResponse> _myHttpGetter(String url,
      {Map<String, String> headers}) async {
    HttpFileFetcherResponse response;
    // Do things with headers, the url or whatever.
    try {
      var res = await http.get(url, headers: headers);
      // add a custom response header
      // to regulate the caching time
      // when the server doesn't provide cache-control
      res.headers.addAll({'cache-control': 'private, max-age=120'});
      response = HttpFileFetcherResponse(res);
    } on SocketException {
      print('No internet connection');
    }
    return response;
  }
}

Now use

class HttpProvider {
  Future<Response> getData(String url, Map<String, String> headers) async {
    var file = await MyCacheManager().getSingleFile(url, headers: headers);
    if (file != null && await file.exists()) {
      var res = await file.readAsString();
      return Response(res, 200);
    }
    return Response(null, 404);
  }
}

Details at https://referbruv.com/blog/posts/caching-get-request-calls-using-flutter-cache-manager and https://proandroiddev.com/flutter-lazy-loading-data-from-network-with-caching-b7486de57f11


UPDATE: flutter_cache_manager 2.0.0

There is no longer a need to extend on BaseCacheManager, you can directly call the constructor. The BaseCacheManager is now only an interface. CacheManager is the implementation you can use directly.

check here

like image 58
Dev Avatar answered Sep 22 '22 13:09

Dev


Another way of caching is by using hive a No-SQL database it is faster to retrieve documents and is easy to use. And when users come online just refresh the data in hive

enter image description here

For more details check:https://github.com/shashiben/Anime-details to know how to cache using hive

like image 39
Shashi Msp Avatar answered Sep 22 '22 13:09

Shashi Msp