Caching is the process of temporarily storing frequently used data or information in a location where it can be accessed quickly and easily, instead of having to retrieve it from its original source every time it is needed.
Caching API responses can improve the performance of your Flutter app by reducing the number of requests made to the server.
Transform your app idea into reality with our Flutter app development services.
In Flutter, caching can be implemented using various packages. We will be discussing the famous and good ones such as shared_preferences
, hive
, sembast
, sqflite
, and others.
Caching Implementation
Shared Preferences package
Let’s start with the simple one i.e. shared_preferences
package:
- Add the
shared_preferences
package to your project by adding it to the dependencies in yourpubspec.yaml
file and runningflutter pub get
. - Import the package in your Dart code:
1 |
import 'package:shared_preferences/shared_preferences.dart'; |
- Use the
SharedPreferences
class to store the API response data in a cache. You can use thesetString
method to store the data and thegetString
method to retrieve it.
1 2 3 4 5 6 7 |
//Store API response in cache SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('api_response', apiResponse); //Retrieve API response from cache SharedPreferences prefs = await SharedPreferences.getInstance(); String cachedResponse = prefs.getString('api_response'); |
- To ensure that the cache is up to date, you can set an expiry time for the cached data. You can store the expiry time in the storage as well and check it before retrieving the data. If the data has expired, you can make a new API request and update the cache.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Store expiry time in cache SharedPreferences prefs = await SharedPreferences.getInstance(); DateTime now = DateTime.now(); int expiryTimeInSeconds = 3600; // 1 hour await prefs.setInt('expiry_time', now.add(Duration(seconds: expiryTimeInSeconds)).millisecondsSinceEpoch); // Retrieve API response and expiry time from cache SharedPreferences prefs = await SharedPreferences.getInstance(); String cachedResponse = prefs.getString('api_response'); int expiryTimeInMilliseconds = prefs.getInt('expiry_time'); // Check if cached data has expired DateTime expiryTime = DateTime.fromMillisecondsSinceEpoch(expiryTimeInMilliseconds); DateTime now = DateTime.now(); if(now.isAfter(expiryTime)) { // Make a new API request and update the cache } |
Note: The shared_preferences
package is not suitable for storing large amounts of data or complex data structures. For more advanced caching needs, you might consider using other packages like hive
, sembast
, or sqflite
.
Hive package
Hive package
Hive
is a NoSQL based database that is optimized for fast read and write operations. Hive is ideal for storing small to medium-sized data sets that can fit in memory, and it is suitable for use cases that require fast read and write performance, such as caching, user preferences, and small data sets.
To integrate Hive with Flutter, you can follow these steps:
- Add the
hive
andhive_flutter
dependencies to yourpubspec.yaml
file:
1 2 3 4 5 6 7 8 9 10 |
#Try to use the latest versions dependencies: hive: ^2.2.3 hive_flutter: ^1.1.0http: ^0.13.5 path_provider: ^2.0.14 http: ^0.13.5 dev_dependencies: build_runner: '>=2.3.0 <4.0.0' hive_generator: ^2.0.0 |
- Now first we create a Hive box and register it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import 'package:hive/hive.dart'; part 'api_response_box.g.dart'; //here my file name is api_response_box.dart @HiveType(typeId: 0) //declare unique for every class class ApiResponseBox extends HiveObject { @HiveField(0) //unique index of the field String url; @HiveField(1) String response; @HiveField(2) int timestamp; } |
- We have to generate a type adapter before we can store objects. Run below command in the terminal:
1 |
flutter pub run build_runner build |
- Let’s register the adapter in our main function:
1 2 3 4 5 6 7 8 9 |
void main() async { WidgetsFlutterBinding.ensureInitialized(); final appDocumentDirectory = await getApplicationDocumentsDirectory(); Hive .init(appDocumentDirectory.path); Hive.registerAdapter(ApiResponseBoxAdapter()); //ApiResponseBoxAdapter will be auto generated with the previous step command runApp(const MyApp()); } |
- Moving forward, creating a helper class to manage caching of API responses:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import 'dart:convert'; import 'package:hive/hive.dart'; import 'package:http/http.dart' as http; class ApiCacheHelper { static const int _cacheTimeout = 60 * 60 * 1000; // 1 hour static const String _baseUrl = 'https://example.com/api'; static Future<Map<String, dynamic>> getJsonResponse(String endpoint) async { final box = Hive.box<ApiResponseBox>('apiResponses'); final cachedResponse = box.values.firstWhere( (response) => response.url == '$_baseUrl/$endpoint', orElse: () => null, ); //returns first element according to the condition or empty object if (cachedResponse != null && DateTime.now().millisecondsSinceEpoch - cachedResponse.timestamp < _cacheTimeout) { // Return cached response if it's not expired yet return json.decode(cachedResponse.response) as Map<String, dynamic>; } // Fetch new response if cache is expired or not available final response = await http.get(Uri.parse('$_baseUrl/$endpoint')); final jsonResponse = json.decode(response.body) as Map<String, dynamic>; // Save new response to cache final newResponse = ApiResponse() ..url = '$_baseUrl/$endpoint' ..response = json.encode(jsonResponse) ..timestamp = DateTime.now().millisecondsSinceEpoch; await box.add(newResponse); return jsonResponse; } } |
- Use the
getJsonResponse()
method ofApiCacheHelper
class to fetch API responses and to cache them
1 |
final response = await ApiCacheHelper.getJsonResponse('api-endpoint'); |
This way we can implement API caching with Hive in the Flutter app. We can adjust the _cacheTimeout
value to set the expiration time of cached responses according to our app’s need.
If you are comfortable with sqflite
package, you can use the same concept with it. Checkout our blog on using sqflite
package.
That’s it from my side. Thanks for reading this article ❤
If I missed something 🙈, then please let me know in the comments. I would love to improve.