Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

So what is the simplest approach for Caching in Flutter? [closed]

Tags:

flutter

dart

The app is a simple news reader which shows WordPress posts, nothing fancy, not using a BLOC, inherited Widget, Firebase. I want it to show the cached data(which is the latest 10 posts) even when the user is offline.

So if the user is offline show Cached data; or somehow default data is cached data.

get the firstPost[Id] from WP REST API If the cached Json file contains Post[id] then show cached data; Else getPosts(); and show loading indicator. also please update the local JSON file.

code to get JSON data:

// Function to fetch list of posts
 Future<String> getPosts() async {
 var res = await http
    .get(Uri.encodeFull(apiUrl + "posts?_embed&per_page=10"), //TODO make it unlimited
        headers: {"Accept": "application/json"});

setState(() {
  var resBody = json.decode(res.body);

  posts = resBody;
});

return "Success!";
}

the future to get posts and shows loading indicator :

  body: FutureBuilder<List<String>>(
      future: getPosts(),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);

        return snapshot.hasData
            ? ListViewPosts(posts: snapshot.data)
            : Center(child: CircularProgressIndicator());
      },
    ),
like image 576
Hooshyar Avatar asked Nov 24 '18 15:11

Hooshyar


People also ask

What is simple caching?

Description. Simple Cache was constructed after getting frustrated with the major caching plugins available and building sites with developer-only complex caching solutions that get millions of page views per day. Simple Cache promises the following: Extremely simple one-click install. There is an on-off switch.

What is the best caching strategy?

Cache-Aside (Lazy Loading) A cache-aside cache is the most common caching strategy available. The fundamental data retrieval logic can be summarized as follows: When your application needs to read data from the database, it checks the cache first to determine whether the data is available.

What are the two types of caching?

L1 cache, or primary cache, is extremely fast but relatively small, and is usually embedded in the processor chip as CPU cache. L2 cache, or secondary cache, is often more capacious than L1.


2 Answers

A simple time-based cache doesn't require much code.

This might help you out. It uses ScopedModel, but it could just as easily be a simple class, although you'd have to either remove the notifyListeners() call or replace it with your own mechanism if you want the model to trigger a refresh of the UI.

class MyModel extends Model{
    Duration _cacheValidDuration;
    DateTime _lastFetchTime;
    List<MyRecord> _allRecords;



    MyModel(){
        _cacheValidDuration = Duration(minutes: 30);
        _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(0);
        _allRecords = [];
    }



    /// Refreshes all records from the API, replacing the ones that are in the cache.
    /// Notifies listeners if notifyListeners is true.
    Future<void> refreshAllRecords(bool notifyListeners) async{
        _allRecords = await MyApi.getAllRecords(); // This makes the actual HTTP request
        _lastFetchTime = DateTime.now();
        if( notifyListeners ) this.notifyListeners();
    }


    /// If the cache time has expired, or forceRefresh is true, records are refreshed from the API before being returned.
    /// Otherwise the cached records are returned.
    Future<List<MyRecord>> getAllRecords({bool forceRefresh = false}) async{
        bool shouldRefreshFromApi = (null == _allRecords || _allRecords.isEmpty || null == _lastFetchTime || _lastFetchTime.isBefore(DateTime.now().subtract(_cacheValidDuration)) || forceRefresh);

        if( shouldRefreshFromApi )
           await refreshAllRecords(false);

        return _allRecords;
    }
}

To get data from MyModel, the UI simply calls getAllRecords(). This will either fetch the records from memory (i.e. from _allRecords) or trigger a refresh which would make a HTTP call and update the records. The cached data automatically expires after 30 minutes, and if you want to force a refresh (for example if the user explicitly taps a refresh button), you can pass forceRefresh: true.

like image 199
Magnus Avatar answered Sep 17 '22 16:09

Magnus


After experiencing many solutions for caching, here is what I’ve learned sorted by complexity:

1- using shared preferences 2- using hive db 3- using firestore offline service 4- using sqflite

like image 41
Hooshyar Avatar answered Sep 21 '22 16:09

Hooshyar