Como os he ido contando en anteriores publicaciones, estamos inmersos en el desarrollo de una APP que más pronto que tarde estará disponible en la Office Store (tengo pendiente un post de como Subir una APP en la Store y no morir en el intento). A lo largo de este desarrollo nos hemos encontrado con algunas limitaciones o aspectos que todavía no están bien definidos dentro de una APP. El primer caso es delñ que vamos a hablar hoy: cómo acceder a la foto de mi perfil desde dentro de una APP. Lo que puede resultar un movimiento relativamente simple resulta algo relativamente complicado dentro de Office 365.
Introducción
Tenemos una APP que solamente tiene una pagina y en la que disponemos de un sitio donde colocar una foto y obtener el nombre del usuario.
- Abrir Visual Studio 2012, crear un proyecto de Aplicación de SharePoint y seleccionamos el tipo de Alojado por SharePoint.
- Dentro de la página default.html (que se ha generado al crear el proyecto) añadir las etiquetas html donde va a estar ubicada la imagen. Algo semejante al siguiente código HTML:
</pre> <div id="imagen"></div> <div id="nombre"></div> <pre>
- Del proyecto generado abrir el fichero App.js y añadirle la consulta a la API Social de SharePoint:
function getProfileUser() { $.ajax( { url: appweburl + "/_api/social.feed/my", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: function (data) { successsProfile(data); }, error: function (data) { failProfile(data); } } ); } function successsProfile(data) { var image ; if (data.d.Me.ImageUri != null) { image = replace(data.d.Me.ImageUri, ' ', '%20'); } var name = data.d.Me.Name; $("#imagen").empty(); $("#nombre").empty(); $("#imagen").html(' <img class="image" title="" alt="" src=" + image + " />'); $("#nombre").html(name); } function failProfile(sender, args) { alert('Error:' + args.get_message()); }
- Dar permisos a nuestra APP para que pueda consultar las caracteristicas sociales para ello hay que ir al manifest.xml de nuestra App e indicarlo. Tal y como esta en la siguiente pantalla:
Problema
Si ahora lanzamos nuestra APP, que nosotros pensamos que esta perfecta se nos visualiza la siguiente imagen:
¿Que es lo que esta ocurriendo para que no muestre la imagen? Se esta produciendo un problema con la autenticación cross-domain de la imagen y debido a esto, SharePoint nos devuelve un error cuando queremos consultar la imagen. Para demostrarlo basta con abrir las herramientas de depuración de vuestro navegador preferido y comprobar que esta ocurriendo cuando se realiza la petición de la imagen:
Posibles soluciones
Lo primero que se me ocurre es que al ser una llamada fuera del dominio quizás tengo que utilizar el Proxy que me permite la llamada entre sitios sin problemas con el CrossDomain, tal y como se pone en este ejemplo. ¿Pero realmente estamos intentando acceder a una pagina de otro dominio y que necesitamos autenticación? La respuesta es clara: no, porque los datos nos lo devuelve, estamos intentando acceder a una imagen de la cual tenemos la URL y al estar dentro de SharePoint no debemos de tener problemas de autenticación.
La siguiente idea es mirar a nuestro «amigo» Google y nos encontramos con este post de Wictor Wilen (MVP SharePoint Server) en el que indica que hay un fallo dentro de SharePoint Enterprise y SharePoint Online. Así que sino activas dentro de tu site el Cross-Domain de la Imágenes no se carga la imagen. Su idea es ejecutar este comando PowerShell y de esta forma se soluciona:
asnp Microsoft.SharePoint.PowerShell $wa = Get-SPWebApplication http://intranet.contoso.com $wa.CrossDomainPhotosEnabled = $true $wa.Update()
Pero esta solución a nosotros no nos vale tal cual está. Porque da por supuesto que podemos acceder a ejecutar una consola PowerShell, nosotros tenemos una APP que encima la queremos vender en la Office Store por lo tanto no podemos ir a cada posible cliente potencial que acceda a la administración central y ejecute un script. No es muy elegante que digamos no? 😛
La siguiente acción que se nos ocurre es que la APP mediante el modelo de objetos en cliente realice esta modificación cada vez que se cargue. Ejecutando este código pero transcrito en JavaScript, la APP sigue sin mostrar la imagen. Una APP no es un site de SharePoint, es un espacio aislado y por lo tanto aunque tenga algunas propiedades iguales que un site no se comporta igual.
¿Como lo solucionamos?
Tras probar todas estas opciones prácticamente no me quedaba otra opción que comentarle esta problemática bien al propio soporte de Office 365, bien a los MVP de SharePoint Server con los que tengo buena relación (Juan Carlos Gonzalez y Alberto Diaz) que nos pudieran ayudar a solucionar este problema.
El soporte de Office 365 nos indico que es un bug que estaban viendo los encargados del producto de como poder solucionarlo (mientras tanto hay que buscar otras opciones para que nuestra APP social pueda tener fotos de perfil).
Ahora bien, el bueno de Alberto Diaz me indica que hay un ejemplo en la MSDN en la que para «saltarse» la autenticación lo que hacen es hacer un iframe oculto y desde este iframe realizar la llamada.
En base a esta idea, la solución para pasarlo a nuestro ejemplo estaba clara: crearnos un iframe donde cargamos la imagen y posteriormente realizar la llamada a la API Social y ver si de esta forma ya teniamos la incidencia resuelta. El código queda de la siguiente forma:
function successsProfile(data) { var image ; if (data.d.Me.ImageUri != null) { image = replace(data.d.Me.ImageUri, ' ', '%20'); } var name = data.d.Me.Name; var blankiframe; var body; blankiframe = document.createElement("iframe"); blankiframe.setAttribute("src", image); blankiframe.setAttribute("style", "display: none"); body = document.getElementsByTagName("body"); body[0].appendChild(blankiframe); window.setTimeout(function() { $("#imagen").empty(); $("#nombre").empty(); $("#imagen").html(' <img class="image" title="" alt="" src=" + image + " />'); $("#nombre").html(name); },2000); }
Como veis, el código es muy similar al anterior: salvo la diferencia de crear un Iframe y asignarle una imagen. A continuación esperamos 2 segundos (tiempo en el que ya tengamos la imagen cargada) y ejecutamos el mismo código que antes y el resultado sería el siguiente:
Conclusión
Como ha quedado claro en este ejemplo, no todo es tan fácil como relativamente parece, el mundo de las APP es de reciente creación y Microsoft aun esta mirando los ajustes y las posibles mejoras para adaptarse tanto a los clientes como a los desarrolladores, mientras todo esto llega y hay un producto final terminado nos toca ir tirando de nuestra habilidad con la plataforma y saltando los posibles inconvenientes que nos encontremos por el camino.
Si os interesa, podeis descargar el ejemplo desarrollado en este artículo.