Post Invitado: Creación de Apps Híbridas con Cordova & Office 365
Siguiendo con la temática de aplicaciones multiplataforma con Apache Cordova, sobre la que hemos ido escribiendo algunos artículos el último mes, queremos ir un paso más allá y explicar cómo crear una aplicación en Apache Cordova que conecte a las APIs de Office 365. Para ello contamos con una colaboración especial. Un post escrito David Mirón, consultor senior de SharePoint y perteneciente al grupo de usuarios [T]echdencias.
¿Qué es Apache Cordova/PhoneGap?
A grandes rasgos, Apache Cordova es un framework de licencia libre que permite a los desarrolladores acceder a la mayoría de características y funcionalidades comunes de las plataformas móviles utilizando tecnología web.
Aquí entra en juego el término “Hibridar”, que no es más que utilizar tecnología nativa para acceder al core o las funcionalidades nativas del dispositivo (cámara, notificaciones, acelerómetro, lista de contactos, etc.) y en segundo lugar también se utilizará tecnología web (HTML5, CSS3 y Javascript) para desarrollar la estructura e interfaz de la propia aplicación.
Desarrollar apps con el framework Cordova tiene una serie de ventajas. Una de las más importantes es la integración de Cordova con Visual Studio y las grandes facilidades que se ofrecen a la hora de poder enlazar o conectar una aplicación móvil desarrollada con Cordova con los servicios expuestos por Office 365.
Servicios de Office 365
En este momento entran en juego la otra cara de la moneda, los servicios de Office 365 a los que vamos a acceder desde nuestra aplicación.
Entre otras características, Office 365 nos expone una API con una serie de funcionalidades o servicios a los cuales vamos a poder acceder mediante scripting.
- OneDrive
- Tareas
- Calendario
- Contactos
- SharePoint
Desarrollo con Office 365
Antes de nada, lo primero que vamos a necesitar es adaptar nuestro Visual Studio para que en primer lugar podamos acceder a la API de Office 365 y en segundo lugar para poder crear aplicaciones de Cordova totalmente integradas.
Dentro de este contexto y partiendo de que tenemos instalado un Visual Studio 2013 con el Update 3 o superior, necesitaremos lo siguiente:
- Office Tools Developer para Visual Studio
- Tools para Apache Cordova
- Cuenta de Office 365 (Development)
En este momento ya estamos preparados para empezar a desarrollar con Cordova y también podremos acceder a la API y a los servicios expuestos por la misma.
En la App que se mostrará en los puntos siguientes, se explicará paso por paso como podemos acceder y mostrar una serie de elementos de lista alojados dentro de un sitio de SharePoint Online mediante la API expuesta por Office 365 a través del framework Cordova.
1. Lo primero que necesitamos es crear el repositorio de datos dentro de SharePoint (Lista) al que vamos a acceder de nuestra aplicación.
2. Seguidamente, lo que vamos a hacer es crear una nueva aplicación de Apache Cordova. Si nos fijamos una vez tengamos instaladas las herramientas anteriores, debería aparecernos un nuevo tipo de proyecto dentro de Templates > Javascript.
Una vez tengamos creada la nueva App de Cordova podremos visualizar una serie de carpetas y scripts por defecto, pero aún no estamos integrados con Office 365.
3. Llegados a este punto, vamos a conectar nuestra App móvil con Office 365. Esto se realiza haciendo click con el botón derecho encima del proyecto y añadiendo los “Servicios Conectados” necesarios tal y como se muestra en la imagen.
Registramos la App, introduciendo las credenciales de la cuenta de Office 365 que vayamos a utilizar para desarrollar y de esta manera podremos asignarle permisos a los Servicios conectados o endpoints expuestos:
Si nos fijamos en la ventana de Output de Visual Studio, cuando registramos la App, Azure automáticamente nos va a asignar un identificador para dicha App la cual quedará registrada en la nube de Azure.
En el caso de esta aplicación concreta, vamos a darle permisos de lectura de los elementos a la capability Sites para poder acceder a la API Rest de SharePoint Online.
Una vez registrada la aplicación, se añadirán automáticamente una serie de scripts (carpeta services) que son los que nos van a permitir acceder al modelo de objetos de cliente de Office 365, SharePoint, Exchange, etc.
Por último, referenciamos los javascripts dentro del fichero index.html de la raíz del proyecto.
<!-- Bloque conexión Office 365 -->
<script src="services/office365/scripts/o365loader.js"></script>
<script src="services/office365/settings/settings.js"></script>
4. Para nuestro ejemplo, vamos a instalar nugets para facilitar y agilizar el desarrollo de la aplicación basándonos en el patrón MVC.
Vamos a necesitar los siguientes:
- Añadir nuget de jquery.
- Añadir nuget de AngularJS Core.
- Añadir nuget de AngularJS Route.
Una vez añadidos los nugets, los referenciamos también dentro del fichero index.html.
5 . A continuación crearemos una carpeta llamada “app” dentro de la carpeta Scripts dentro de la cual añadiremos nuestras vistas y controladores. En esta aplicación vamos a crear dos vistas. La primera de ellas simplemente será un botón para realizar el login con Office 365 y la segunda nos mostrará los datos de la lista de SharePoint a la que queremos acceder.
Antes de empezar a crear las vistas, vamos a implementar un Factory que nos va a permitir realizar la autenticación contra el Azure AD y nos va a devolver los tokens necesarios para poder realizar peticiones a la API de Office 365.
(function () {
'use strict';
angular.module('app365').factory('app365api', [app365api]);
function app365api() {
var authContext;
var authtoken;
var authOptions;
var discoveryContext;
var rootSiteCapability;
// Login to O365
function login(callback) {
//Permite a buscar el token ID de y también el token de acceso necesarios
if (!authContext) {
authContext = new O365Auth.Context();
}
//Permite buscar las capabilites/servicios que expone la API
if (!discoveryContext) {
discoveryContext = new O365Discovery.Context();
}
discoveryContext.services(authContext.getAccessTokenFn('Microsoft.SharePoint')).then((function (value) {
var capabilities = value;
//Recupero exclusivametne la capability de RootSite (SharePoint Sites)
capabilities.forEach(function (v, i, a) {
if (v.capability === 'RootSite') {
rootSiteCapability = v;
}
});
//Objeto que me permitira acceder al contexto de autorización y a la capability rastreada
authOptions = { capability: rootSiteCapability, authContext: authContext, token: value };
callback();
}).bind(this), function (reason) {
// Log sign-in error message.
console.log('Failed to login. Error = ' + reason.message);
callback(reason.message);
});
};
// Logout
function logout() {
if (!authContext) {
authContext = new O365Auth.Context();
}
authContext.logOut();
};
return {
login: login,
logout: logout,
authOptions: function () { return authOptions; }
};
};
})();
Principalmente, esta clase constará de dos métodos. Uno de ellos para realizar el login y el otro para realizar el logout contra Office 365.
Para realizar cualquier operación con la API de Office 365 vamos a necesitar los llamados objetos de contexto:
if (!authContext) {
authContext = new O365Auth.Context();
}
if (!discoveryContext) {
discoveryContext = new O365Discovery.Context();
}
- El objeto authContext le permite a buscar el token ID de y también el token de acceso necesarios, que pueden utilizarse para obtener información de los usuarios y para llamar a los servicios que expone la API.
- El objeto discoveryContext le permite a buscar las capacidades de servicio de Office 365, como Mail o calendario o MyFiles, junto con sus endpoints correspondientes. Una vez que tenga el símbolo de identificación deseado, puede ser usado para identificar al usuario.
Pasándole el token de autenticación devuelto por el objeto O365Auth al objeto O365Discovery se nos redireccionará al endpoint de autenticación del AD de Azure donde tendremos que añadir nuestras credenciales de Office 365. Con esto, ya tendremos disponible el acceso a todos los endpoints de la API.
discoveryContext.services(authContext.getAccessTokenFn('Microsoft.SharePoint')).then((function (value) {
var capabilities = value;
Por último, y para poder acceder desde nuestra app, vamos a almacenar las capabilities y el contexto de autenticación dentro de un objeto.
authOptions = { capability: rootSiteCapability, authContext: authContext };
6. Creados los métodos para autenticarnos en Office 365 crearemos las vistas y controladores necesarios para nuestra aplicación y las introduciremos dentro de la carpeta app. La estructura de carpetas y ficheros de la carpeta App quedará de la manera siguiente:
- Script enrutador. A través del plugin AngularRoute Este script simplemente se encargará de redireccionarnos a una vista u otra.
var app365 = angular.module('app365', [
'ngRoute']);
app365.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'scripts/app/auth/loginView.html',
controller: 'loginCtrl'
}).
when('/homeView', {
templateUrl: 'scripts/app/index/homeView.html',
controller: 'homeCtrl'
})
}
]);
- Controlador de login. Se encargará de pasarle los parámetros necesarios al Factory y nos redireccionará automáticamente a la vista homeview.html.
(function () {
'use strict';
angular.module('app365').controller('loginCtrl', ['$scope', '$location', 'app365api', loginCtrl]);
function loginCtrl($scope, $location, app365api) {
$scope.signIn = function () {
app365api.login(onlogin);
};
var onlogin = function (reason) {
$location.path("/homeView");
$scope.$apply();
};
}
})();
- Controlador de HomeView. Aquí se realizará la consulta REST pasándole el token de acceso y se recuperarán los datos de la lista de SharePoint online consultada.
function getListItemsCapability() { authOptions.authContext.getAccessToken(authOptions.capability.resourceId).then((function (bearerToken) { $.ajax({ type: 'GET', headers: { "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "Authorization": "Bearer " + bearerToken }, url: authOptions.capability.resourceId + '/sites/dev/_api/web/lists/getbytitle(\'Clientes\')/items', success: function (data) { jQuery.each(data.d.results, function (i, listItem) { $scope.aClientes.push({ Titulo: listItem.Title, Sector: listItem.Sector }); }); $scope.$apply(); }, error: function (data) { alert(data); } }); })); }
}
Si nos fijamos, se utiliza el objeto authContext para recuperar el token necesario para poder realizar las consultas REST que le pasamos a la consulta AJAX dentro del parámetro “Authorization”.
7. Una vez tenemos creadas todos los scripts necesarios de las vistas, vamos a referenciar todos estos scripts dentro del fichero index.html de la raíz y vamos a adaptar este mismo archivo para realizar el binding con el módulo de Angular llamado app365.
8. Si ejecutamos la aplicación que acabamos de crear con el emulador de Android activado llegaremos a la vista donde aparece el botón para realizar el login, que como ya hemos comentado antes nos redireccionará al endpoint de Azure AD encargado de realizar la autenticación.
Cuando nos autentiquemos con nuestras credenciales tendremos que autorizar a la aplicación para que tenga los permisos que anteriormente hemos asignado para poder visualizar elementos de listas de SharePoint.
En último lugar, después de haber hecho el login de manera correcta y autorizada a la aplicación con los permisos determinados sobre Office 365, tendremos nuestra aplicación lista y nos mostrará los elementos guardados en la lista de Clientes creada dentro de SharePoint.
Espero que os sirva de ayuda y os animéis a adentraros en el mundo de Apache Cordova y la integración con Office 365 pronto.
David Mirón