Contenido
- Obtención de apikey y apisecret para la utilización de Eventbrite API
- Creación de proyecto y de aplicación
- Estructura de la aplicación
- Lógica de inicio de aplicación: main.ms
- Experiencia de login: LoginExperience.ms
- Experiencia lista de eventos: EventsExperience.ms
- Edición de Layouts – Creación de Templates
Obtención de apikey y apisecret para Eventbrite API
Para poder comunicarse con la API de eventos de Eventbrite, primero necesitarás crear una app eventbrite siguiendo los siguientes pasos:
- Registrarse en la red social de eventos www.eventbrite.com e iniciar sesión.
- Acceder al menu ‘Account Settings’
- Acceder al menu ‘Developer > App Management’
- Presionar botón ‘CREATE NEW APP’
- Completar la información de contacto y los detalles de la información de tu aplicación. El campo redirect URI se utiliza en el protocolo como re-dirección de la vista web de Eventbrite luego del login exitoso. Aquí debes ingresar un sitio web accesible para completar en los campos de URL y URI (sin importar si la URI existe). Si no cuentas con un sitio web propio simplemente puedes ingresar el de matr, por ejemplo: (http://matrproject.com/ y http://matrproject.com/redirect_oauth). De todos modos, puedes volver a editar esta información en cualquier momento.
- Aceptar términos y condiciones, presionar ‘CREATE APP’ , y eso es todo!
Ahora puede visualizar en tu lista de aplicaciones los campos que necesitas para el proceso de OAuth. Cópiate y guarda los valores de los campos ‘client key’ y ‘client secret’ (recuadrados de la siguiente imagen), junto con la ‘OAuth Redirect URI’ ingresada en el paso 5, estos serán necesarios para iniciar el proceso y tendrás que agregarlos en tu código en la LoginExperience.ms.
Creación de proyecto y de aplicación
Si todavía no cuentas con ningún proyecto, puedes acceder a la sección Projects
y crear un nuevo proyecto presionando el botón con el signo ‘+’ y completando los datos como se observa en la siguientes imagenes:
Luego creamos una nueva aplicación presionando el botón con el signo ‘+’ y completamos los datos como se observa a continuación:
Estructura de la aplicación
Una vez creada nuestra aplicación, procedemos a darle forma. La misma estará compuesta de 3 archivos:
main.ms
: en donde se definirán variables globales, constantes, modelos, librerías importadas y la lógica de inicio de la aplicación.LoginExperience.ms
: aquí crearemos un experiencia para la autenticación del usuario.EventsExperience.ms
: el archivo que contendrá la experiencia que será responsable de la carga y visualización de los eventos.
Para crear los archivos, procedemos a hacer click en el icono ‘+’ ubicado en la barra de tareas por debajo de los diferentes tabs que posee nuestro IDE. A continuación podemos observar los archivos creados:
Observa que el archivo main.ms
ya fue creado por defecto, te aconsejamos borrar su contenido y editarlo como explica la siguiente sección del tutorial.
Lógica de inicio de aplicación: main.ms
En nuestro primer archivo llamado main.ms
, realizamos lo siguiente:
- Crearemos un Modelo llamado
User
, el cual contendrá toda la información del usuario logueado.
Model User {
String name
String email
String eventbriteId
}
- Definiremos todas las variables globales que usaremos en la aplicación, dentro del bloque
Aplication
.
Application {
//Constants
String ebUserTokenKey
String loggedUserNameKey
String loggedUserEventbriteIDKey
//Global App Models
User loggedUser
String token
- Inicializamos las variables dentro del bloque
OnInit
, el cuál es el primer bloque de código que se ejecutará al cargar la aplicación. Observar que las primeras 2 variables serán utilizadas como claves de los métodos de persistencia.
OnInit {
ebUserTokenKey = "ebUserTokenKey"
loggedUserNameKey = "loggedUserNameKey"
loggedUserEventbriteIDKey = "loggedUserEventbriteIDKey"
- Dentro del mismo bloque, escribiremos toda la lógica de inicio de la aplicación. Aquí haremos uso de los servicios de acceso y control del gps y activaremos el GPS del dispositivo:
try {
if (broker.location.hasGPS()) {
broker.location.start()
}
} catch (e) {
//handle exception e.reason()
}
Luego, utilizando las funciones de acceso al almacenamiento local del dispositivo consultamos si el usuario ya se encuentra logueado (de una sesión anterior). En caso afirmativo, recuperamos el usuario logueado y lo asignamos en la variable loggedUser
; hacemos algo similar con la variable token
recuperando el valor por medio del almacenamiento local encriptado, sentencia broker.localKeychain.get(); y por ultimos mostramos la experiencia EventsExperience
que mostrará la lista de eventos, por medio de la sentencia de navegacion broker.ui.push().
En caso contrario, mostramos la experiencia de login: LoginExperience
.
if (broker.localPersistence.hasKey(loggedUserNameKey)) {
//already logged user
loggedUser = User(name: broker.localPersistence.get(loggedUserNameKey), eventbriteId: broker.localPersistence.get(loggedUserEventbriteIDKey) )
token = broker.localKeychain.get(ebUserTokenKey)
broker.ui.push("EventsExperience")
} else {
//must show login
broker.ui.push("LoginExperience")
}
- Importamos la librería
EventBriteLibrary
que contiene los servicios que se comunican con la API de Eventbrite, de donde la aplicación consultará los datos de los eventos a mostrar. Librerias como esta y muchas otras podrás encontrar en el mat|r hub e importarlas para acelerar tu desarrollo. La guia completa para crear e importar librerias puedes verla aqui.
La expresión para importar la librería es la siguiente, y debes agregarla al inicio del archivomain.ms
:
Import EventBriteLibrary as EventBriteLib
Una vez hecho esto, podremos observar todos los modelos y servicios importados. En nuestro ejemplo utilizaremos dos servicios: uno para obtener los datos del usuario logueado, llamado eb_getProfile
; y otro para obtener los eventos cercanos llamado eb_getEventsByLocation
.
Si colocamos el puntero sobre el nombre de cada servicio, podemos observar los parámetros necesarios para poder hacer uso de ese servicio, como se muestra a continuación:
El código completo de nuestro archivo main.ms
puedes visualizarlo aqui.
Experiencia de login LoginExperience.ms
En este archivo, vamos a definir:
- Una experiencia llamada
LoginExperience
que contendrá un botón, y que al presionar el mismo ejecutará una regla llamadaruleSingInEventbrite
, para esto agregamos unaExperience
y unDecision
, de la siguiente forma:
Experience LoginExperience {
Decision ruleSingInEventbrite action("LoginContext.ruleSingInEventbrite") label("Signin with Eventbrite")
}
- Luego definiremos la regla
ruleSingInEventbrite
, que contendrá la configuración de un modelo OAuth con los valores necesarios para la autenticación y la llamada al servicio broker para que realice dicha autenticación. Es importante observar que aqui debes completar los atributosclientID
,secret
yredirectURL
, por los campos correspondientes obtenidos en la creación de la app eventbrite al inicio del tutorial, estos son ‘client key’ y ‘client secret’ y ‘OAuth Redirect URI’.
OAuth oauth = OAuth()
oauth.clientID = "...COMPLETE..."
oauth.secret = "...COMPLETE..."
oauth.redirectURL = "...COMPLETE..."
oauth.accountName = oauth.clientID + oauth.secret
oauth.authorizationURL = "https://www.eventbrite.com/oauth/authorize?response_type=token&client_id=" + oauth.clientID
oauth.tokenURL = "https://www.eventbrite.com/oauth/token"
token = broker.oauth.authenticate(oauth)
La llamada broker.oauth.authenticate(oauth)
abrirá una vista web donde el usuario debe ingresar sus credenciales de acceso de la red social Eventbrite. Al término de este proceso el usuario se encuentra logueado y autenticado, con lo cuál obtendremos el token
necesario para llamar a los servicios definidos en la librería que importamos anteriormente.
Primero haremos la llamada para obtener los datos del usuario logueado, invocando el servicio EventBriteLib::eb_getProfile
:
La llamada recibe como argumento el token y retorna un nuevo modelo EventBriteLib::EBProfileResponse
:
EventBriteLib::EBProfileResponse profileRsp = service.EventBriteLib::eb_getProfile.call(token)
Posteriormente, crearemos una instancia del modelo User
con dichos datos:
loggedUser = User(name:profileRsp.name, eventbriteId:profileRsp.eventbriteId)
y guardaremos en el almacenamiento local los atributos del modeloUser
y el token, para poder validar en un posterior acceso a la aplicación si el usuario ya había iniciado sesión y obtenido un token válido (esta lógica es la que habíamos definido anteriormente en el archivo main.ms).
broker.localPersistence.save(loggedUserNameKey, loggedUser.name)
broker.localPersistence.save(loggedUserEventbriteIDKey, loggedUser.eventbriteId)
broker.localKeychain.save(ebUserTokenKey, token)
El código completo de nuestro archivo LoginExperience.ms
puedes verlo aqui.
Experiencia lista de eventos EventsExperience.ms
Por último, en este archivo definiremos:
- Una experiencia en la que se mostrará una lista con los eventos obtenidos a través de un servicio (importado por nuestra librería) y se mostrará el nombre del usuario logueado. Para esto agregamos a la experiencia un
String
que se mostrará en su layout como un componenteLabel
y unArray
de los modelos (importados de la librería)EventBriteLib::EBEvent
, que se mostrarán en un componente de UI de tipoList
.
Experience EventsExperience {
String name as Label
Array<EventBriteLib::EBEvent> events as List
}
- Dentro de la experiencia, el método
OnCreate
, se ejecuta cada vez que la experiencia es creada. En este lugar, obtenemos el datasource asociado al layout de la experiencia mediante la llamadabroker.ui.getDataSource()
que asignamos a la variable localexp
, para luego asignar sobre el atributoname
el nombre del usuario logueado que tenemos referenciado desde la variable globalloggedUser
.
OnCreate {
EventsExperience exp = broker.ui.getDataSource()
exp.name = loggedUser.name
}
- Dentro de la experiencia, realizaremos la carga de los eventos a partir de la ubicación actual del dispositivo, en el método
OnResume
, que se ejecuta cada vez que la experiencia vuelve a ser visible.
Para esto, realizamos una llamada al servicio EventBriteLib::eb_getEventsByLocation
, con los parámetros requeridos que podemos ver en la siguiente imagen:
Primero debemos configurar el formato que utiliza la API de eventbrite para parsear las fechas y esto lo logramos con la siguiente sentencia:
service.EventBriteLib::eb_getEventsByLocation.setDateFormatter(DateFormatter(format: "yyyy-MM-dd'T'HH:mm:ssZ", utcTimeZoneOffset: 0))
Luego efectuamos la llamada, con lo siguientes parámetros (en el orden de la llamada):
- ‘token’: obtenido desde el login
- ‘latitud’ y ‘longitud’ (obtenidos del servicio broker.location.getLocation())
- ‘within’: que establece el rango en kilometros para filtrar los eventos resultantes en la consulta.
- ‘pageNumber’: el número de página a consultar, puesto que el servicio soporta paginación.
Location userLoc = broker.location.getLocation()
EventBriteLib::EBEventResponse response = service.EventBriteLib::eb_getEventsByLocation.call(token, userLoc.latitude, userLoc.longitude, 25, 1)
asignamos los eventos recuperados en la lista de nuestra experiencia para que sean mostrados, y por último en caso de que no encontremos eventos mostramos un mensaje:
experiencia.events = response.events
if (response.events.size() == 0) {
broker.ui.showAlert("Oops","No events found!")
}
El código completo del archivo EventsExperience.ms puedes verlo aqui.
Edicion de Layouts – Creación de Templates
Una vez que tenemos listo el codigo de la aplicación, podemos pasar a ver cuales son los layouts que se van a auto-generar correspondientes a las experiencias que han sido creadas anteriormente, en el tab Build UI
de nuestro IDE. En nuestro ejemplo, se autogeneran dos layouts: LoginExperience
y EventsExperience
, como podemos observar a continuación:
En esta vista de edición de UI, que llamamos UI Builder
podrás customizar a gusto todos los elementos visuales. Haciendo click en el componente o en el panel izquierdo en la jerarquía de vistas, podrás observar en el panel derecho, sección Properties
todas las propiedades visuales editables para el mismo.
Si intentamos ejecutar la aplicación en estas condiciones, obtendremos un error ya que en la experiencia EventsExperience
estamos asociando una lista de modelos (en este caso EBEvent) a un componente visual List
. Para que esto funcione, necesitamos crear un layout específico para mostrar cada uno de estos eventos en la lista, a estos layouts especiales los llamamos templates
.
Por lo tanto procederemos a crear un template, desde el tab Build UI
, clickeando sobre el segundo botón ‘+’, y nombrando al archivo ‘template_event_cell’ como observamos a continuación:
El nuevo template creado traerá un label por defecto. Agregamos 2 nuevos componentes: uno de tipo label
y otro de tipo image
. Asi tendremos en total 2 labels y una imagen donde mostraremos el nombre, fecha e imagen del evento. Esto lo hacemos haciendo click sobre el componente visual ubicado en el lado izquierdo del IDE, el mismo será agregado a la vista y obtenemos lo que podemos ver a continuación:
Luego, para cada elemento visual del template debemos establecer cuál será la clave a utilizar para el bindeo de datos. Para esto hacemos click sobre el componente mismo (o en la estructura de árbol del lado izquierdo de la pantalla). En el componente de tipo image
podemos observar la propiedad llamada Data binding
en donde seteamos valor eventImage
:
Hacemos lo mismo con los otros componentes de tipo label, al primero le pondremos ‘eventStart’ y al segundo ‘eventName’.
Ya estamos listos para bindear los datos a mostrar de la lista de eventos en la experiencia EventsExperience
. Primero seleccionamos el layout EventsExperience
asociado a la experiencia desde el menú lateral izquierdo, luego seleccionando de la lista y por último, sobre el panel derecho la propiedad Template and data binding
.
Desde allí seleccionamos el template a utilizar: ‘template_event_cell’ y establecemos para cada clave definida anteriormente (‘eventStart’, ‘eventName’ y ‘eventImage’) un atributo o cadena de atributos del modelo a bindear, de la siguiente manera:
{{item.atributo}}
donde ‘item’ hace referencia a un modelo del tipo definido en la lista, y ‘atributo’ al nombre de un atributo de un modelo. Notar que se pueden encadenar en caso de que los atributos sean a la vez modelos.
En nuestro ejemplo, sabemos que la lista que estamos configurando:
Array<EventBriteLib::EBEvent> events as List
esta compuesta por modelos de tipo EventBriteLib::EBEvent
. Si observamos el atributo start
:
es a la vez un modelo de tipo EventBriteLib::EBDate
que tiene un atributo utc
de tipo Date
que indica la fecha de inicio del evento y contendrá el valor a mostrar, por lo cual en el binding para ese campo debemos ingresar: “{{item.start.utc}}”.
Con un razonamiento similar, el binding a configurar sobre la clave ‘eventName’ es “{{item.name.text}}” y el de la clave ‘eventImage’ es “{{item.logo.url}}”.
Y asi tenemos la primera versión de nuestra aplicación lista!!
Ejecutando la aplicación podrás ver las siguientes pantallas, con layouts autogenerados:
Por supuesto, con ayuda del UI Builder
puedes embellecer tus layouts a gusto y así mejorar la apariencia visual de tu aplicación. Si quieres que tus pantallas queden igual que las
que se muestran al inicio del tutorial puedes hacer lo siguiente:
- Accede a la edición por XML del layout LoginExperience en la sección
Build UI
:
Reemplaza el XML autogenerado (que representa la definición del layout) por el XML de aquí.
- Selecciona el template ‘template_event_cell’, accede a la edición por XML y reemplaza el XML autogenerado por el XML de aquí.
Salva los cambios y listo! Cuando vuelves a correr la aplicación verás tu aplicación con la misma UI que te mostramos al inicio, con un aspecto profesional!