I recently was trying to use an offline cache with OkHttp to store some information. This is handy if the user goes offline and we want them to still see some information.
I'd been following this great little tutorial by Annyce Davis on Caster.io. I have used a Retrofit instance with offline caching before, but I had never actually set one up myself. In previous apps when I've needed to cache something I stored it in a database. Caching with OkHttp seems handy where you're not doing much with the data. For example if you're presenting a simple news article and want the user to be able to read offline. It would be easier than setting up the boilerplate code needed for a database.
So I got my Interceptor
setup with Dagger and created an offline Retrofit instance.
@Provides
@Singleton
@Named("offline-cache-interceptor")
Interceptor provideOfflineCacheInterceptor (final Application context) {
return new Interceptor()
{
@Override
public Response intercept (Chain chain) throws IOException
{
Request request = chain.request();
if ( !NetworkUtil.isNetworkConnected(context))
{
CacheControl cacheControl = new CacheControl.Builder()
.maxStale( 1, TimeUnit.DAYS )
.build();
request = request.newBuilder()
.cacheControl( cacheControl )
.build();
}
return chain.proceed( request );
}
};
}
The service for the API I was hitting used this and I was happy. Except no offline caching. I entered the app while online and got my data, put the app in airplane mode, pressed the home button and then re-entered the app. Blank TextView
. This frustrated me to no end. The code looked near enough identical to all examples I could find. I delved into the files on my device looking for the cache file but nothing. So I did what I thought would be best, I left it.
A few months on and I came back to the app. I wanted to give the problem another go. I did some searching, trying to find someone with similar issues. And boom. Jesse Wilson, creator of OkHttp, stated that POST requests can not be cached with OkHttp. What was I using? Yep, a POST. Luckily I could switch to a GET (which actually made more sense in this context). Low and behold, I had glorious offline caching.
The irony is that after I fixed this I decided that it would be better for me to store and manage this in a database.
Go figure ¯\(ツ)/¯