Skip to content
This repository has been archived by the owner on Dec 7, 2019. It is now read-only.

Recipes (Spanish)

Mike Nakhimovich edited this page May 30, 2017 · 1 revision

Bienvenido a las recetas de Store!

Creando Stores

Existen 3 puntos de entrada en StoreBuilder que pueden ser usados para construir un store. Las diferencias en cuando usar cada uno depende si es que tienes tu propio Key Type y si es que tendras un parser.

public final class StoreBuilder {
...
    public static <Parsed> RealStoreBuilder<Parsed, Parsed, BarCode> barcode()

    public static <Key, Parsed> RealStoreBuilder<Parsed, Parsed, Key> key()

    public static <Key, Raw, Parsed> RealStoreBuilder<Raw, Parsed, Key> parsedWithKey()
...
}

Datos en caché luego actualizados

Primero llama get y concatena el resultado con fecth. A continuación, agrega el operador distinct que sólo permitirá emisiones únicas. Si la caché y la red retornan el mismo valor o si la primera llamada get necesita ir a la red, sólo se emitirá 1 elemento.

store.get(barCode)
                .concatWith(store.fetch(barCode))
                .distinct()
                .subscribe()

Nota: Si es que omites distinct() siempre recibiras dos elementos

Mantenerse Suscritos para futuras emisiones.

store.stream()
                .subscribe()
  • Nota: Stream continuará obteniendo emisiones para CUALQUIER barcode. Puedes utilizar el operador filter para escuchar un subconjunto de resultados.

Refresh when clear

A veces deseas obtener nuevos datos cada vez que tu store es limpiado. Un caso de uso común es querer hacer un rerequest de datos a la red cada vez que un usuario envía una solicitud POST diferente. El método publico de store getRefreshing(key) te permite llamar a store.clear(key) en cualquier momento que desees que tu observable se repita(hacer una llamada a la red). Ejemplo de uso:

allNotesStore.getRefreshing(barCode)
                .subscribe(observer);

notesApi.submitNewNote(barcode);

allNotesStore.clear(barcode); //cuando clear es llamado, store hara un request a la red de nuevo

Refresh on Stale

Cuando estas usando un Persister es posible que desee volver a llenar su caché de disco en cualquier momento en que el registro es obsoleto. Para ello, agregue un método adicional a su StoreBuilder e implemente RecordProvider o utilice nuestro built in RecordPersister store = StoreBuilder.barcode() .fetcher(fetcher) .persister(persister) .refreshOnStale() .open();

    Store<ArticleAsset, Integer> store = StoreBuilder.<ArticleAsset>barcode()
            .fetcher(articleBarcode -> api.getAsset(articleBarcode.getKey(),articleBarcode.getType()))
          .persister(new RecordPersister(FileSystemFactory.create(context.getFilesDir()),5, TimeUnit.HOURS))
            .open();

Network on Stale

Cuando estas usando un Persister es posible que desees actualizar tus datos haciendo un request a internet antes de retornar datos en disco que estan obsoletos. Para ello, agregue un método adicional a su StoreBuilder e implemente RecordProvider o utilice nuestro built in RecordPersister store = StoreBuilder.barcode() .fetcher(fetcher) .persister(persister) .networkBeforeStale() .open();

    Store<ArticleAsset, Integer> store = StoreBuilder.<ArticleAsset>barcode()
            .fetcher(articleBarcode -> api.getAsset(articleBarcode.getKey(),articleBarcode.getType()))
          .persister(new RecordPersister(FileSystemFactory.create(context.getFilesDir()),5, TimeUnit.HOURS))
            .open();

Caché de disco suprimible

Si desea que store.clear(key) también limpie su caché de disco, haga que su Persister implemente Clearable

MultiParser

Algunas veces usted quiere usar un parser intermediario(middleware) que convierta de json a un pojo y luego use otro parser para desempaquetar tus datos.

       Parser<BufferedSource, RedditData> sourceParser = GsonParserFactory.createSourceParser(provideGson(), RedditData.class);
       Parser<RedditData, Data> envelopeParser = redditData -> redditData.data();

       ParsingStoreBuilder.<BufferedSource,RedditData>builder()
               .fetcher(this::fetcher)
               .persister(persister)
               .parser(new MultiParser<>(Arrays.asList(sourceParser,envelopeParser)))
               .open();

Top Level JSON Array

En algunos casos necesite convertir un JSONArray que se encuentra en un nivel superior(top level JSONArray), en el cual puedes proveer un TypeToken.

Store<List<Article>> Store = ParsingStoreBuilder.<BufferedSource, List<Article>>builder()
                .nonObservableFetcher(this::getResponse)
                .parser(GsonParserFactory.createSourceParser(gson, new TypeToken<List<Article>>() {}))
                .open();

Política de caché de memoria perzonalizadas

Por defecto stores almacenarán en caché hasta 100 elementos durante 24 horas utilizando una política expireAfterAccess. Puedes pasar tu propia instancia de Cache para sobreescribir la duración y tipo de política de almacenamiento en caché. El siguiente ejemplo almacenará 1 elemento para siempre, lo que le permitirá mantener la huella de memoria del store baja.

ParsingStoreBuilder.<BufferedSource,RedditData>builder()
                .fetcher(this::fetcher)
                .parser(GsonParserFactory.createSourceParser(provideGson(),RedditData.class))
                .memory(CacheBuilder.newBuilder()
                        .maximumSize(1)
                        .expireAfterWrite(Long.MAX_VALUE, TimeUnit.SECONDS)
                        .build())
                .open();

Heredando Stores

Hay momentos en los que le gustaría construir un store con algunos métodos auxiliares adicionales. Heredando de store es su mejor apuesta. Con base en lo que pasa en el constructor se denotará cómo se configura el store.

public class SampleStore extends RealStore<String, BarCode> {
   @Inject
   public SampleStore(Fetcher<String, BarCode> fetcher, Persister<String, BarCode> persister) {
        super(fetcher, persister);
    }
}

Almacenamiento en caché de disco con FileSystemPersister

Si desea habilitar el almacenamiento en caché de disco, la forma más sencilla es usar Source Persister agregando compile 'com.nytimes.android:filesystem:VERSION' to your build.gradle

Un source persister puede persistir algo que es un BufferedSource. Más fácilmente puede obtener un BufferedSource de Okhttp Response o Retrofit ResponseBody. Si utiliza un cliente de red diferente en su fetcher, puede crear un BufferedSource con:

Okio.buffer(Okio.source(new ByteArrayInputStream(data.getBytes(UTF_8))))

Si viene de un inputStream

Okio.buffer(Okio.source(inputStream))

Una vez que tienes un fetcher que devuelve un BufferedSource puedes crear un FileSystemPersister Persister

Persister<BufferedSource, BarCode> persister = FileSystemPersister.create(fileSystem, key ->"Book"+key.getType()+key.getKey())

Cuando utilice FileSystemFactory, debe proporcionar un PathResolver. El motivo de un PathResolver es permitir el uso compartido del mismo FileSystem entre varios stores.

StoreBuilder.<BufferedSource>builder()
                .fetcher(this::fetcher)
                .persister(persister)
                .open();

La mayoría de los casos de uso se quiere parsear los datos hacia un pojo en lugar de devolver un BufferedSource middleware parsers funcionan perfectamente con el SourcePersister

ParsingStoreBuilder.<BufferedSource,RedditData>builder()
                .fetcher(this::fetcher)
                .persister(persister)
                .parser(MoshiParserFactory.createSourceParser(new Moshi.Builder().build(),RedditData.class))
                .open();
                .parser(JacksonParserFactory.createSourceParser(new ObjectMapper(),RedditData.class))
                .parser(GsonParserFactory.createSourceParser(new Gson(),RedditData.class))