Backendless BaaS

Buenas a todos,

Después de la retirada de Parse, me decidí por Backendless como mi backend para mis aplicaciones Android. La segunda opción era Firebase, pero finalmente me decidí por Backendless.

En este post quiero explicar todo el procedimiento desde la creación de la cuenta de Backendless, siguiendo por la especificación de los objetos, la descarga de datos siguiendo la API Rest de backendless, hasta la presentación en la aplicación.

El ejemplo que usaremos será sencillo, una simple lista de datos inflada desde nuestro backend. En este caso será una lista con los nombres de nuestros amigos y su fecha de cumpleaños, pero como veremos, cambiar esto por vuestro caso particular es muy sencillo.

1. Preparación de backendless

Lo primero que debemos hacer es crearnos una cuenta en backendless. Una vez logueados en la plataforma, navegaremos hasta la pestaña de ‘Datos’.

El siguiente paso será la creación de la tabla ‘Amigos’ que contendrá tres columnas: nombre, teléfono y fecha de cumpleaños. Para ello, se debe hacer click en el signo ‘+’ situado en el esquina inferior izquierda de la pestaña ‘Datos’.

Una vez creada la tabla ‘Amigos’, crearemos sus columnas. Es conveniente hacer click en el botón rojo ‘Esquema de tablas y permisos’. Añadiremos tres columnas, todas de tipo String. El resultado ha de ser algo parecido a esto:

Captura de pantalla 2016-04-16 a las 19.14.57

Una vez creadas las columnas, se debe rellenar la base de datos. Rellenaremos con datos al azar para este ejemplo. Quedaría algo así:

Captura de pantalla 2016-04-16 a las 19.20.07

2. Android

El proyecto va a constar de una única activity con un recyclerview. Primero vamos a crear el modelo de datos, en nuestro caso Amigo. Es importante que los atributos se llamen iguales que las columnas creadas en backendless. La clase debe tener constructor, además de getters y setters para todos sus atributos.

/**
 * Created by josedelpozo on 16/4/16.
 */
public class Amigo {

    private String nombre;
    private String telefono;
    private String cumple;

    public Amigo(String nombre, String telefono, String cumple) {
        this.nombre = nombre;
        this.telefono = telefono;
        this.cumple = cumple;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getTelefono() {
        return telefono;
    }

    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

    public String getCumple() {
        return cumple;
    }

    public void setCumple(String cumple) {
        this.cumple = cumple;
    }
}

La respuesta de Backendless es un JSON con atributos de offset, un array de Amigos, un link a la siguiente página y el número de total de objectos que aparecen en el array. Es necesario crear una clase como esta:

/**
* Created by josedelpozo on 17/4/16.
*/
public class BackendlessResponse {

private String offset;
private List<Amigo> data;
private String nextPage;
private float totalObjects;

public BackendlessResponse(String offset, List<Amigo> data, String nextPage, float totalObjects) {
this.offset = offset;
this.data = data;
this.nextPage = nextPage;
this.totalObjects = totalObjects;
}

public String getOffset() {
return offset;
}

public void setOffset(String offset) {
this.offset = offset;
}

public List<Amigo> getData() {
return data;
}

public void setData(List<Amigo> data) {
this.data = data;
}

public String getNextPage() {
return nextPage;
}

public void setNextPage(String nextPage) {
this.nextPage = nextPage;
}

public float getTotalObjects() {
return totalObjects;
}

public void setTotalObjects(float totalObjects) {
this.totalObjects = totalObjects;
}
}

Una vez terminado el modelo, comenzamos con la descarga de datos desde backendless. Como comenté, vamos a usar la API Rest. Para facilitarnos la vida, vamos a usar la librería Retrofit 2.0. Así que, se debe añadir a build.gradle las siguiente líneas:

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'

compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

El siguiente paso es crear una interfaz, ‘AmigoService’ que define el método a llamar para recuperar nuestros amigos.

/**
 * Created by josedelpozo on 17/4/16.
 */
public interface AmigoService {

    @Headers({"application-id: APP-ID",
            "secret-key: SECRET-KEY",
            "Content-Type: application/json"})
    @GET("/{version}/data/{table-name}")
    Call<BackendlessResponse> getAmigos(@Path("version") String version, @Path("table-name") String table);
}

Vamos a pararnos un momento en este método. Primero se han de definir unas cabeceras que indican una conexión segura hacia nuestra cuenta de backendless. El id de aplicación, y la clave secreta rest se deben copiar y pegar de nuestro dashboard de backendless. Además, definimos que lo que vamos a recibir es un json con los datos de nuestros amigos.

 

Lo siguiente indica que es una petición GET, e indica la dirección a la que haremos dicha petición. En este caso, la versión de nuestra aplicación es v1 y el nombre de la tabla ‘Amigos’.

Este método devuelve un objeto de tipo Call<Object>, siendo object lo que queremos recibir ya parseado. En nuestro caso, BackendlessResponse.

Bien, una vez creado el servicio, hagamos la petición. Como va a ser una aplicación tan sumamente sencilla que solo descargará estos datos, la petición se hará sobre la Activity que mostrará los datos, pero esto no es Clean Code y no se debe hacer así.

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.backendless.com")
.addConverterFactory(GsonConverterFactory.create())
.build();

final AmigoService service = retrofit.create(AmigoService.class);

Call<BackendlessResponse> call = service.getAmigos("v1", "Amigos");
Callback callbackRetrofit = new Callback<BackendlessResponse>() {
@Override
public void onResponse(Call<BackendlessResponse> call, Response<BackendlessResponse> response) {
adapter.addAll(response.body().getData());
}

@Override
public void onFailure(Call<BackendlessResponse> call, Throwable t) {
Log.d("ERROR","Failure "+t.getMessage());
}
};
call.enqueue(callbackRetrofit);

Este código será el encargado de hacer la petición a la dirección https://api.backendless.com que se especifica en el objecto Retrofit. También se especifica que usaremos Gson para parsear de JSON a nuestro objecto Amigo.

 

Seguidamente creamos el servicio, y llamamos al método definido en la interfaz anterior. Realizaremos la petición de forma asíncrona, eso quiere decir que cuando el servidor nos devuelva la respuesta, nos aparecerá en el callback definido. Si no ha habido fallo, esta aparecerá en onResponse, y en caso contrario en onFailure.

Para mostrar estos datos, es necesario montar un recyclerview sobre nuestro layout, y un adapter que muestre esos datos. Este tema no lo voy a comentar aquí, ya que es muy sencillo y hay miles de tutoriales más detallados. El código si que lo dejaré en Github por si alguien quiere consultarlo.

Captura de pantalla 2016-04-17 a las 10.46.29

¡El resultado es este!

GITHUB

Tuenti Challenge 2016

Hola otra vez!

Hace unos días me llegó un email de la UPM avisándome de ‘Tuenti Challenge’, un concurso de código. Estos temas me llaman mucho la atención. El año pasado competí en el 1 primer concurso de aplicaciones Android Cátedra BQ, y después de mucho esfuerzo, conseguí hacerme con el primer premio.

Leyendo las bases del concurso, me gustó mucho el que pudiera elegir el lenguaje que yo quisiera. El concurso comienza el 25 de abril y dura hasta el 3 de mayo. Durante ese tiempo tengo que resolver el máximo número de retos que pueda.

He estado leyendo los enunciados de los challenge de años anteriores, y la temática es parecida. Algoritmos matemáticos, criptografía, man in the middle… interesante cuanto menos.

La dificultad en cada reto es superior al anterior, así que los primeros retos deberían llevarme poco tiempo.

Os iré contando tanto mi entramiento hasta el 25 de abril, como un diario durante los días de concurso.

Espero que os guste!

 

Saludos.

Rating Bar

Hola de nuevo!

Estoy haciendo una app para poder votar a los profesores de la universidad, y así, ser por fin nosotros quienes ponen la nota.

Cuando la aplicación estaba casi terminada, en su primera versión, me di cuenta que la RatingBar de Google no se podía dimensionar en tamaño. O al menos, no lo encontré en su guía, ni me funcionaron ninguno de los consejos de stackoverflow.

Captura de pantalla 2016-03-24 a las 11.21.47

Como veis, el tamaño de las estrellas es demasiado grande. Si intento disminuir su height, para que no sean tan grandes, ya que de ancho si quiero que ocupen todo, ocurre lo siguiente:

Captura de pantalla 2016-03-24 a las 11.24.18

Así que, miré varios ejemplos y me decidí a realizar mi propia RatingBar. Os dejo el link a Github, y si alguien quiere ayudar en el proyecto que no dude!

StarsRatingBar

Saludos!

Aprendiendo Kotlin

Hola a todos!

Hace ya un mes que me cree el blog, y aún no me he atrevido a escribir ningún post.

Llevo ya bastante tiempo siguiendo a @lime_cl, y me interesé por Kotlin, el nuevo lenguaje que Antonio lleva tiempo explicando. Como bien os comenté en el primer post explicatorio sobre lo que iba a ir mi blog, os dije que estaba intentando aprender clean architecture y Dagger 2, así que, se me ocurrió crear un ejemplo con esto desarrollado en Kotlin.

El ejemplo se encuentra en Github, lo podéis obtener aquí. KotlinSeries

Además, tengo pensado desarrollar el mismo código en Java para poder comparar entre ambos lenguajes. Sería interesante observar el número de líneas que te ahorras usando Kotlin.

MVP

La estructura del proyecto está basada en MVP + Repository. El ejemplo muestra una lista de Series que se presentan ordenadas alfabéticamente. Por el momento está lista es rellenada por un fake, es decir, no hay conexión con ningún servidor ni DB, cosa que queda como objetivo para el futuro.

No voy a entrar en detalle de como se estructura el modelo MVP, ya que hay demasiado escrito sobre ello y al final del post os dejaré unas referencias muy interesantes. Pero sí os voy a contar como lo desarrollo yo.

Mis vistas, ya sean activity o fragment, siempre tienen un presenter. Llegado el caso que la vista tenga varias funcionalidades bien distintas, podría tener un presenter por cada funcionalidad. En el proyecto cada Activity tiene un presenter que se encarga de obtener notificaciones de la vista, y devolverle la contestación necesaria.

Cada activity suele tener una funcionalidad, que viene implementada por un caso de uso. La separación de estos casos de uso es estrictamente necesaria para mantener código limpio y fácilmente escalable. El caso de uso se encargará de solicitar al repository los datos que necesita.

En este test, como los datos son fake, no hay servidor, no aparece la función del ‘DataSource’, tema que abordaré cuando le incluya el servidor para descarga de datos.

El esquema sería el siguiente:

Captura de pantalla 2016-03-09 a las 23.10.50

Kotlin vs Java

¿El post no iba de Kotlin?

Sí, en esta parte del post quería enseñaros las principales diferencias que he visto con Java.

Clases

Escribir clases con Java acaba siendo un verdadero coñazo, aunque con el generate… de Android Studio todo se simplifica. Sin embargo, las clases de objeto suelen definir varios setters/getters, además de un método equals o un toString.

En Kotlin vale con una línea para todo lo descrito anteriormente:

data class Serie(val name: String, val description: String, val image: String)

Hebras

En Java la descarga de datos se debe realizar en otra hebra que no sea la Main para no ralentizar la App. Por eso, se debe crear una nueva hebra, hacer la petición de descarga de datos, y una vez que se recibe la respuesta hay que volver a la Main Thread para mostrar los datos. En Kotlin el funcionamiento es el mismo, sólo que con bastante menos líneas de código.

fun getAll(callback : (ArrayList&lt;Serie&gt;?) -&gt; Unit) {
        async() {
            var list = repository.getAll()
            uiThread {
                callback(list)
            }
        }
    }

Esto es posible gracias a la librería Anko.

Callback

Si alguno ha podido ver ya, el método anterior recibe como parámetro un callback. En Java para poder hacer esto era necesario crear una interfaz con un método, y implementarlo donde se llamara a la función. De nuevo, Kotlin elimina código innecesario y la llamada a getAll quedaría de la siguiente forma:

getSeries.getAll(){
    if(it?.size!!.compareTo(0) &amp;gt; 0){
        view?.hideLoading()
        (view as SeriesPresenter.View).showSeries(it)
    }else{
        view?.hideLoading()
        (view as SeriesPresenter.View).showEmptyCase()
    }
}

Cuando aparece la llamada a getAll no se le pasa ningún parámetro, aunque reciba el callback comentado anteriormente. Esto es porque el corchete que se abre seguidamente representa ese callback. La palabra reservada it sirve para recibir el parámetro, en este caso un ArrayList con las Series a mostrar.

Null Safety

Durante el código aparecen ? ó ! ó incluso !!. Gracias al operador ? nos salvamos de la archiconocida NullPointerException que tanta lata da.

Conclusión

Además de estas posibilidades comentadas, Kotlin ofrece otras muchas que aún no he tenido tiempo de investigar y probar.

Me decidí a probarlo por las grandes similitudes que vi con Swift, y he quedado impresionado con las posibilidades y la facilidad en el código. Como todo lo nuevo, supone una curva de aprendizaje al principio lenta, pero es un lenguaje que merece la pena conocer.

Creo que una de sus mayores virtudes podría ser la alternancia en el mismo proyecto de código Java y código Kotlin, ya que cada uno podría ser útil en un aspecto distinto o incluso para el uso de librerías con poca compatibilidad con Kotlin seguir usándolas en Java.

Espero seguir mejorando este ejemplo, y en posteriores post hablar sobre Dagger 2 y funcionalidades nuevas a implementar.

Referencias

Kotlin – Antonio Leiva – http://antonioleiva.com/kotlin/

MVP – Antonio Leiva – http://antonioleiva.com/mvp-android/

My way to clean Android – Christian Panadero – http://panavtec.me/my-way-to-clean-android/

Nueva experiencia

Hola a todos!

Bueno, pues aquí comienza un nuevo proyecto que llevo varias semanas pensando. Me apetecía empezar a escribir un blog sobre temas de Swift y Android, compartiendo código y vivencias que he ido pasando durante los proyectos que se presentarán.

El principal objetivo de este blog es aprender a programar en esos dos lenguajes que tanto me apasionan. Cuando digo aprender a programar, me refiero a mejorar en cuanto a nivel de código, claridad y técnicas para mejorar la calidad del código.

Últimamente estoy intentando mejorar mis conocimientos de Android aprendiendo Clean architecture e inyección de dependencias con Dagger 2. Creo que los próximos posts irán sobre este tema.

Espero no defraudar!

Saludos

@josedlpozo