Javi Moreno Apuntes Fichas de Lectura Archivo Sobre mi
Blog Logo

Javi


9 minutos de lectura

Tal y como anticipe que sucedería, durante estos días he estado probando Helios, el framework de @mattt que nos permite crear un backend para aplicaciones móviles.

Como ya hice un primer análisis del framework en conjunto, ahora me voy a ir centrando en las piezas que lo forman siguiendo el orden, para mi, de mayor a menor importancia. La idea es que en las próximas semanas pueda ir sacando artículos sobre cada una de ellas:

  1. Sincronización de datos. Core Data Buildpack + AFIncrementalStore
  2. Notificaciones Push. Rack::Push Notification + Orbiter
  3. In-App Purchases. Venice + Cargo Bay
  4. Passbook. Dubai/Rack::Passbook

Sigo teniendo sentimientos encontrados con este framework. Por un lado creo que supone un gran avance ya que simplifica enormemente el desarrollo propietario de una serie de servicios indispensables para una aplicación móvil actual. Por otro lado creo que frameworks de desarrollo web como Ruby on Rails o Sinatra no son mucho más complicados y las posibilidades que ofrecen son infinitamente mayores.

Empezemos...

Sincronización de datos

Hace algunos meses, Heroku publicó un tutorial en el que mostraba como crear un backend a partir de un proyecto iOS con Core Data. El mismo tutorial proponía realizar la sincronización con AFIncrementalStore, un framework basado en NSIncrmentalStote (una nueva clase no muy conocida) y que usa AFNetworking para las conexiones REST. Según el articulo de NSHipster sobre NSIncrementalStore con menos de 300 líneas de código tenemos una sincronización que nos quitará muchos quebraderos de cabeza. "It just works", dice. Unas palabras malditas siempre que se habla de sincronización de datos en la nube.

AFIncrementalStore no funciona bien a día de hoy. ¡Anda! igual que iCloud. He estado varios días intentando hacerlo funcionar pero al final no he conseguido nada. Supongo que es cosa de tiempo ya que hay una enorme comunidad de desarrolladores detrás intentando hacerlo funcionar.

Backend

Helios usa Core Data Buildpack para generar el modelo REST al arrancar el servidor. Necesita una base de datos PostgreSQL para funcionar y un poquito de configuración, pero hacerlo andar con una estructura de tablas por detrás es coser y cantar. Ojo con el modelo REST: tendremos todos los endpoints habituales para hacer las operaciones CRUD pero una cosa fundamental como son los filtros, a día de hoy, no están desarrollados y desconozco si lo estarán algún día ya que en el roadmap no se habla de ellos. Si por algún motivo no lo vas a necesitar en tu backend, perfecto, Helios se ajusta al 100% a tu servicio aunque yo creo que lo normal es incluir algún filtro en el endpoint: un campo de ordenación, el número de registros por página, filtrado por usuario. Creo que solo hay algo que se utilice más que la cláusula WHERE en SQL... el operador AND:

Helios puede usarse solo ya que por dentro es una aplicación hecha en Sinatra pero también pueden integrarse la gema en un proyecto Rails o Sinatra, actuando como middleware. En el repositorio recomiendan que se proteja este middleware con seguridad ya que podrá contener datos de gran sensibilidad.

En este post, aprovecharé para explicar muy brevemente como incluir la gema en un proyecto Rails e incorporar una seguridad HTTP básica.

Mi idea era usar Helios para hacer una especie de Google Reader. AFIncrementalStore me ha desinflado un poco la idea pero sigue siendo la base del backend.
Supongo que cada uno seguirá su método; en mi caso, antes de empezar con la aplicación web, lo primero que haremos será crear un proyecto iOS con Core Data donde definiremos el modelo: dos tablas, una para almacenar los feeds a los que estamos suscritos y otra para almacener los elementos descargados de cada feed.

Usaremos el API de Google Reader que se ocupa de descargar los feeds ya que devuelve siempre el mismo resultado, independientemente de que lea de un rss o de un atom. Este API seguro que desaparece el 1 de Julio de 2013 pero de momento nos ayudará a tener una buena copia de seguridad de nuestros blogs favoritos.

Empezamos a desarrollar.

Una vez que hemos creado un xcdatamodel en Xcode, lo que hacemos es crear una aplicación Rails que sirva para contener el backend Helios y además nos permita crear todo aquello que no nos proporciente este framework, como por ejemplo la securización del repositorio, las cuentas de usuario, etc.

En el terminal escribiremos lo siguiente:

$ rails new DealerErgoGo -d postgresql

Directamente trabajaremos con PostgreSQL desde desarrollo por lo que tenemos que tener instalado en nuestro equipo este gestor de base de datos. Mi recomendación es usar Postgres.app, desarrollada por Mattt (que tío) que funciona muy bien y es fácil de instalar (relativamente).

Lo primero que haremos en nuestro proyecto Rails es configurar el acceso a la base de datos, solo cambiamos el usuario y le indicamos el puerto y el host. Creamos las bases de datos y a disfrutar.

$ rake db:create

A continuación incluimos todo lo necesario para usar Helios.

Instalamos la gema y creamos la base de datos

$ rake db:create

Siguiendo las instrucciones del repositorio, configuramos Helios como un middleware en application.rb. Aprovecharemos para incluir el modelo de datos que hemos creado en la aplicación iOS dentro de la carpeta de configuración de la aplicación Rails. En local no es necesario pero cuando hagamos el despliegue en Heroku, tendremos que subir el modelo junto con la aplicación.

# Using framework Helios as a middleware for our app
    config.middleware.use Helios::Application do
        service :data, model: './config/DealerErgoGo.xcdatamodel'
        service :push_notification
        service :in_app_purchase
        service :passbook
    end

Securizamos desarrollo y producción con seguridad HTTP básica

# Autenticación HTTP Básica para no dejar al descubierto los datos de la aplicación
  config.middleware.insert_after(::Rack::Lock, "::Rack::Auth::Basic", "Who R' U?") do |u, p|
    u == ENV["USERNAME"] && p == ENV["PASSWORD"]
  end

Cargamos las variables de entorno de nuestro fichero

# Load the environment variables at beginning
  config.before_configuration do
    env_file = File.join(Rails.root, 'config', 'local_env.yml')
    YAML.load(File.open(env_file)).each do |key, value|
    ENV[key.to_s] = value
    end if File.exists?(env_file)
  end

Para terminar, cambiamos el adaptador de postgresql a postgres porque sequel, una dependencia que trae Helios, lo usa. Debido a esto es muy importante configurar y crear la base de datos antes de introducir Helios en la aplicación ya que de lo contrario entraremos en un bucle infinito de cambio de adapatores. También cambiamos el usuario de la base de datos ya que, por defecto, PostgreSQL solo tendrá nuestro usuario local.

development:
  adapter: postgres
      encoding: unicode
      database: DealerErgoGo_development
      pool: 5
  username: javi
      password:
  host: localhost
  port: 5432

Y con esto ya tendríamos listo el backend. Podríamos probarlo en nuestra máquina local o desplegar directamente en Heroku. Para ello solo hay que tener Heroku toolbelt instalado, haber hecho commit de todos los cambios en la rama y principal y desde la carpeta del proyecto en el terminal escribir lo siguiente:

$ heroku create

Para crear la aplicación y

$ git push heroku master

Para desplegar la aplicación en Heroku. Listo, ya podemos disfrutar de nuestras 750 horas gratuitas al mes.

La decepción

Nos las prometíamos muy felices. El desarrollo y puesta en producción del backend había sido tan sencillo que confiábamos en que la creación de la aplicación iOS fuera igual y en realidad, esto no ha sido así.

Para desarrollar la aplicación vamos a seguir este tutorial de la web de Heroku. Aparentemente no es muy complicado y de hecho no lo es, el problema es que cuando hayamos seguido todos los pasos y tengamos la aplicación lista para envíar datos a nuestro flamante servidor veremos que la grabación la hace bien pero el retorno de la información no y nuestra aplicación empieza a fallar. Llevo toda la semana leyendo las issues del repositorio y buscando en Stackoverflow a ver si doy con el correcto funcionamiento pero hasta ahora no he conseguido nada. Creo que es algo que se me ha pasado por alto en algún punto ya que es demasiado evidente que no está funcionando como para que no haya ninguna queja al respecto. En cualquier caso, yo mismo pondré un issue a ver si me pueden echar una mano.

Conclusiones

Si tu aplicación necesita de subir los datos a un servidor o simplemente leer unos datos sencillos: datos del tiempo, noticias, entradas de un blog, radares móviles,... Helios te puede ser de una gran ayuda. No recomiendo que uses AFIncrementalStore si no que, de momento, sería mejor que te hicieras tu propia sincronización con Core Data.

Si ves que Helios se te empieza a quedar pequeño porque necesitas filtrar los datos en el servidor y no en la propia aplicación, no tengas miedo a dar el paso a Ruby on Rails. Llevará un poco más de trabajo pero no mucho más y eso ya si que es dar un salto cualitativo en la creación de tu propio backend ya que tendrás mucho más control sobre el mismo.