Created
April 29, 2019 07:54
-
-
Save Marchuck/7b1e6573c631c7a61306eb29cbb3c36a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//offline-first usecase for api requests | |
//one you have to do is to include rxjava to your project, | |
//some Api(could be Retrofit based), | |
//some Preferences(could SharedPreferences based / some database), | |
//some SerializerUtil (could be gson, moshi) | |
import com.google.gson.JsonSyntaxException; | |
import com.google.gson.annotations.SerializedName; | |
import io.reactivex.Observable; | |
import io.reactivex.functions.Consumer; | |
import java.io.Serializable; | |
import java.util.concurrent.Callable; | |
public class CacheEnabledUseCase { | |
public static final String KEY_CACHED_RESPONSE = "KEY_CACHED_RESPONSE"; | |
private final Api api; | |
private final Preferences preferences; | |
private final SerializerUtil<YourResponse> serializerUtil; | |
class YourResponse implements Serializable { | |
@SerializedName("field1") | |
public String field1; | |
@SerializedName("field2") | |
public String field2; | |
} | |
interface SerializerUtil<T> { | |
String serialize(T any); | |
T deserialize(String json, Class<T> klazz) throws JsonSyntaxException; | |
} | |
interface Api { | |
Observable<YourResponse> fetchResponse(); | |
} | |
interface Preferences { | |
String getString(String key, String defaultValue); | |
void putString(String key, String value); | |
} | |
public CacheEnabledUseCase(final Api api, | |
final Preferences preferences, | |
final SerializerUtil<YourResponse> serializerUtil) { | |
this.api = api; | |
this.preferences = preferences; | |
this.serializerUtil = serializerUtil; | |
} | |
public Observable<YourResponse> execute() { | |
final YourResponse cachedResponse = getCachedResponseOrNull(); | |
if (cachedResponse != null) { | |
return executeCached(cachedResponse) | |
.concatWith( | |
executeFreshAndPersist().onErrorResumeNext(Observable.<YourResponse>empty())//if fresh failed, only cached will be emitted | |
); | |
} else { | |
return executeFreshAndPersist(); | |
} | |
} | |
private Observable<YourResponse> executeCached(final YourResponse cachedResponse) { | |
return Observable.fromCallable(new Callable<YourResponse>() { | |
@Override | |
public YourResponse call() { | |
return cachedResponse; | |
} | |
}); | |
} | |
private Observable<YourResponse> executeFreshAndPersist() { | |
return api.fetchResponse() | |
.doAfterNext(new Consumer<YourResponse>() { | |
@Override | |
public void accept(YourResponse yourResponse) { | |
putToCache(yourResponse); | |
} | |
}); | |
} | |
private void putToCache(YourResponse successfullResponse) { | |
String res = serializerUtil.serialize(successfullResponse); | |
preferences.putString(KEY_CACHED_RESPONSE, res); | |
} | |
private YourResponse getCachedResponseOrNull() { | |
String json = preferences.getString(KEY_CACHED_RESPONSE, null); | |
if (json != null) { | |
try { | |
return serializerUtil.deserialize(json, YourResponse.class); | |
} catch (JsonSyntaxException x) { | |
//empty catch block. if it is failed, no cache is supported | |
} | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment