MSDN Blogs
  • WarNov Developer Evangelist

    Efecto Navideño para blogs usando HTML5

    • 2 Comments

    Luego de implementar el citado evento en mi propio blog, he recibido muchas preguntas de cómo lo logré.

    image

    He aquí la respuesta:

    Este trabajo es basado en un algoritmo de Javascript para HTML5 creado por David Flanagan que se basa en generar un elemento canvas por cada copito de nieve bajando en el blog. Entonces cada copo de nieve se agrega al DOM y es animado usando posicionamiento a través de CSS. Sin embargo se puede mejor usar un solo canvas y animar los copos dentro de este tal como lo sugiere Giorgo Sardo, con el fin de ahorrar memoria. Esto sin embargo puede producir que se bloquee la interacción normal con la página… es así que lo mejor es poner el canvas en un background de menor prioridad (atrás del contenido) tal como lo pueden ver en mi blog.    

    Este es el JavaScript requerido:

    (function () {
    
        // Start Animation only if browser support <canvas>
        if (document.createElement('canvas').getContext) {
            if (document.readyState === 'complete')
                Snow();
            else
                window.addEventListener('DOMContentLoaded', Snow,
    false); } var deg = Math.PI / 180; //Degrees to radians var sqrt3_2 = Math.sqrt(3) / 2; //Height of an eq triangle var flakes = []; // Things that are dropping var scrollspeed = 64; // How often we animate things var snowspeed = 500; // How often we add a new snowflake var maxflakes = 20;//Max number of flakes to be added var rand = function (n) { return Math.floor(n *
    Math.random()); } var canvas, sky; var snowingTimer; var invalidateMeasure = false; function Snow() { canvas = document.createElement('canvas'); canvas.style.position = 'fixed'; canvas.style.top = '0px'; canvas.style.left = '0px'; canvas.style.zIndex = '0'; document.body.insertBefore(canvas,
    document.body.firstChild); sky = canvas.getContext('2d'); ResetCanvas(); snowingTimer = setInterval(createSnowflake,snowspeed); setInterval(moveSnowflakes, scrollspeed); window.addEventListener('resize', ResetCanvas, false); } function ResetCanvas() { invalidateMeasure = true; canvas.width = document.body.offsetWidth; canvas.height = window.innerHeight; sky.strokeStyle = '#0066CC'; sky.fillStyle = 'white'; } function drawFlake(x, y, size, order) { sky.save(); sky.translate(x, y); snowflake(order, 0, Math.floor(sqrt3_2 * y), size); sky.fill(); sky.stroke(); sky.restore(); } function snowflake(n, x, y, len) { sky.save(); // Save current transformation sky.beginPath(); sky.translate(x, y);
    // Translate to starting point sky.moveTo(0, 0); // Begin a new subpath there leg(n); // Draw the first leg of the fractal sky.rotate(-120 * deg);
    // Rotate 120 degrees anticlockwise leg(n); // Draw the second leg sky.rotate(-120 * deg); // Rotate again. leg(n); // Draw the final leg sky.closePath(); // Close the subpath sky.restore();
    // Restore original transformation // Draw a single leg of a level-n Koch snowflake. // Leaves the current point at the end of // the leg it has drawn and translates the coordinate // system so the current point is (0,0).
    // This means you // can easily call rotate() after drawing a leg.
    function leg(n) { sky.save(); // Save current transform if (n == 0) { // Non-recursive case: sky.lineTo(len, 0);// Just a horizontal line } else { // Recursive case: _ _ // draw 4 sub-legs like: \/ sky.scale(1 / 3, 1 / 3);
    // Sub-legs are 1/3rd size leg(n - 1);
    // Draw the first sub-leg sky.rotate(60 * deg);
    // Turn 60 degrees clockwise leg(n - 1);
    // Draw the second sub-leg sky.rotate(-120 * deg);
    // Rotate 120 degrees back leg(n - 1); // Third sub-leg sky.rotate(60 * deg);
    // Back to original heading leg(n - 1); // Final sub-leg } sky.restore(); // Restore the transform sky.translate(len, 0);// Translate to end of leg } } function createSnowflake() { var order = 2; var size = 10 + rand(90); var t = (document.body.offsetWidth - 964) / 2; var x = (rand(2) == 0) ? rand(t) : t + 964 + rand(t);
    // Make it fit with my blog var y = window.pageYOffset; flakes.push({ x: x, y: y, vx:
    0, vy: 3 + rand(3), size: size, order: order }); if (flakes.length > maxflakes)
    clearInterval(snowingTimer); } function moveSnowflakes() { sky.clearRect(0, 0, canvas.width, canvas.height); var maxy = canvas.height; for (var i = 0; i < flakes.length; i++) { var flake = flakes[i]; flake.y += flake.vy; flake.x += flake.vx; if (flake.y > maxy) flake.y = 0; if (invalidateMeasure) { var t = (canvas.width - 964) / 2; flake.x = (rand(2) == 0) ?
    rand(t) : t + 964 + rand(t); } drawFlake(flake.x,flake.y,flake.size,flake.order); // Sometimes change the sideways velocity if (rand(4) == 1) flake.vx += (rand(11) - 5) / 10; if (flake.vx > 2) flake.vx = 2; if (flake.vx < -2) flake.vx = -2; } if (invalidateMeasure) invalidateMeasure = false; } }());
    Felices fiestas!

    snowflake, snow effect, JavaScript, html5, css, canvas, animation, christmas, blog

  • WarNov Developer Evangelist

    Heridas de guerra en la publicación de apps al Windows Store

    • 2 Comments

    No son tan graves como el título; pero tener conocimiento de ellas, nos ayudará a evitar tener que perder tiempo en envíos/rechazos de nuestras apps al store.

    Este artículo contiene información extraida de este post de uno de nuestros MVPs. Se trata de Roberto Alvarado, quien ha estado trabajando mucho con el desarrollo móvil, aún desde Windows Mobile. Así que me he permitido invitarle a mi blog con su post acerca de esta experiencia y él muy amablemente quiso acompañarnos. También tiene información extraida de este post de Juan Carlos Ruiz, colega mío dentro de Microsoft Colombia, y finalmente de mis propias experiencias desde que ha estado al aire el store de Windows. Es así como primero listaré las observaciones de Roberto y luego las de Juan, adicionando algunos comentarios donde sea requerido: 

    De Roberto Alvarado:

    1. Seleccionar el idioma de la App y de la tienda.

    image

    Independiente que el idioma de Visual Studio sea ingles, el idioma de la aplicación y sobre el cual se certificará en la tienda debe ser claro y especifico.

    En mi caso, el idioma es español y en Colombia.

    Nota de WarNov: Este cambio de idioma tan importante se ejecuta dentro de Visual Studio. No en el store. Se hace en el archivo  Package.AppManifest que tiene un editor visual para hacer el cambio. Los detalles de este procedimiento los pueden encontrar en este post que he creado.

    2. La descripción de la aplicación que se va a colocar en la tienda debe ser una frase que tenga mínimo 7 palabras, no debe ser una palabra. Debe describir de manera rápida y sencilla lo que hace la aplicación.

    image

    3. Se deben enviar mínimo 2 imágenes de 1366 x 768, a pesar de que solo se exige 1, si se envía 1 imagen nos rechazan la App.

    image

    4. Es muy importante tener una pagina web o Url en donde se publique una Política de privacidad para nuestra App.

    image

    Si no tiene una, puede utilizar esta, que fue provista por WarNov para su difusión: tiene el texto tanto en ingles como en español. http://bdotnet.wix.com/privacypolicy

    Además tu App debe tener un charm en donde indique la política de privacidad que utilizas, en este link te indico como puedes crear este charm: Crear página de Política de Privacidad de un App Windos 8

    Nota de WarNov: Solo es requerido que tu app incluya una política de privacidad, si en las capacidades de la app dentro del manifiesto de la misma, se especifica que la app se conecta a internet:

    image

    En el ejemplo ven el manifiesto de mi app PhotoRanker y como ven, dado que mi app no usa internet, no requiere una política de privacidad.

     

    5. Llenar o dar las instrucciones necesarias al equipo de testing en el store, sobre el manejo de la aplicación para que no sea rechazada porque no la saben manejar.

    image

    En la imagen un ejemplo sobre este punto.

    6. Es muy importante el rango de edad en el cual coloca su App, si su rango de edad es de 3 años o superior, o de siete años o superior, su App no debe tener conexión a Internet ni hacer utilización de la cámara del dispositivo.

    image

    Tengamos muy en cuenta las opciones y recomendaciones que nos da la misma tienda de Windows para ubicar nuestra App en uno de los rangos de fechas disponibles.

    En este momento no hay posibilidad si no de estas 4 opciones para nuestro App.

    Nota de WarNov: Para la mayoría de Apps, es recomendable escoger el límite de edad 12+.

    7. La imágenes del App, si verificamos la carpeta Assets del explorador de soluciones de Visual Studio, debemos dejar los mismos nombres de las imágenes, el mismo formato y principalmente las mismas dimensiones de lo contrario nuestra App será rechazada el momento de ejecutar el kit de Certificación de App para Windows 8.

    Un ejemplo de esto:

    image

    Si cambia el nombre de la imagen del logo por ejemplo debe indicarlo en el manifiesto también del App de manera correcta.

    8. Si utiliza una base de datos local, como SQLite, debe asegurarse que en las propiedades del proyecto en la pestaña de Compilación (Build) esté seleccionado el procesador correcto de su PC, y asegurarse que en las referencias del proyecto, la referencia de SQLIte no tenga una advertencia, si la tiene, elimine la referencia y vuelva a crear la referencia a SQLite.

    9. Al publicar su App debe asegurarse que tener en “Release” su App al momento de las compilaciones y verificaciones que se realizan con el KIT de Certificación.

    image

     

    De Juan Carlos Ruiz:

     

    1. Website

      • La aplicación debe estar publicada en un sitio web del publicador o uno específico para la App con vínculos claros que permitan descubrir la aplicación a los usuarios a través de la pagina web
      • No tienes sitio web? no sabes como crearlo? hay muchas formas de crear sitios web sencillos rápidamente sin una línea de código, solo búscalos en internet Guiño

    Nota de WarNov: No es necesario crear un sitio web para la app como tal. Por ejemplo poner tu url de twitter como desarrollador, será suficiente. Aunque sin lugar a dudas, es mucho mejor tener un website dedicado a la app donde tengas info de la misma como instrucciones y changelog, tal como lo hice para mi app PhotoRanker, usando los WebSites de Windows Azure, que son totalmente gratuitos.

    2. Estabilidad

    • Cero fallos después de abrir y cerrar varias veces
    • Desconexión de red, la app no debe hacer crash si no hay dispositivos de red o la red esta caída
    • Desconexión internet la app no debe hacer crash si no hay conexión a internet
    • La aplicación no debe presentar ningún fallo o app crash durante su uso

     

    3. Contenidos

    • Aptos para todos: no sexo explícito , no agredir religiones, no terrorismo, no discriminación de ninguna índole
    • Si la aplicación se clasifica en el rating para niños menores de 7 años NO SE PUEDE HACER USOS DE DISPOSITIVOS NI DE INTERNET, en este caso la aplicación debe considerarse para mayores de 7años de forma obligatoria.
    • Si la aplicación puede mostrar contenidos sensibles como desnudos artísticos parciales o violencia real moderada etc. se recomienda establecerla para mayores de 16 años

     

    4. Funcionalidad

    • La aplicación DEBE soportar Snapped View, con esto no digo que tengan que desarrollar esta vista adicional, pero por lo menos sino lo hacen deben evitar que en ese espacio se muestre la información de manera desordenada o desagradable , en dado caso sino se va a soportar la funcionalidad entonces colocar una banner que cubra todo el espacio, tal como lo hace la propia App del Windows Store
    • Si implementan funcionalidades de búsqueda, esta debe estar creada usando el Charm de búsqueda (Search), cualquier implementación diferente causa el rechazo de la App.

    Nota de WarNov: De la anterior regla de búsqueda, quedan excluidas las apps que tengan funcionalidades de búsqueda avanzada que requieran de más de un campo de búsqueda. Por ejemplo una app para buscar vehículos para comprar puede requerir buscar por modelo, color o placa. En este caso, sí se justifica una búsqueda adicional a la incluida en el charm.

    • No deben haber botones para cerrar la App
    • Si en el manifest se marca que la App soporta determinadas posiciones de la tableta, así debe ser, si falta alguna de las seleccionadas la aplicación es devuelta.
    • La app no debe ser solo para mostrar publicidad, la publicidad debe ser utilizada en justa medida, pero no puede ser el objeto principal de la App.
    • La aplicación debe ser 100% funcional utilizando solo dispositivos Mouse y Teclado
    • La aplicación debe ser 100% funcional utilizando solo dispositivos Touch
    • La aplicación debe tener descripción adecuada, todos los logos necesarios y screenshots en Windows Store y en el Package.appmanifest
    • La aplicación no debe incluir en su nombre palabras como “trial”, “test”, “beta”, “demo” , si es requerido informar que la aplicación esta en etapa preliminar, utilizar la palabra "preview"
    • La aplicación no debe tener en la pantalla principal ninguna característica, marco, tableta, botón o label que indique que es una funcionalidad futura, es decir evitar palabras como "coming soon”, “more to come”, “not available yet” . "próximamente", "en construcción" etc.
    • Las funcionalidades principales de la aplicación no deben re direccionar el usuario al browser. Solo características no principales en el 2do o 3er nivel de navegación son permitidas para direccionar al browser. Las funcionalidades principales deben estar dentro de la App.
    • Se recomienda incluir información para soporte técnico en el Charm de configuración (settings ) y en la página web de la aplicación, con alguno de los siguientes mecanismos de contacto:
        • email de contacto
        • url
        • teléfonos etc.

    5. Información para Windows Store

    • Si la aplicación requiere de usuario y contraseña u otros mecanismos para garantizar el acceso a todas sus características se debe enviar junto con la aplicación la información de acceso necesaria para realizar las pruebas. Hay una sección llamada ‘Notas para testers’ donde se debe depositar dicha información.
    • Si la aplicación requiere información o trámites de pago para activar funcionalidades, en las notas para los testers se debe incluir información de pago que puedan utilizar para acceder a estas características de la aplicación y realizar pruebas.
    • Validar que toda la información del Windows Store este correctamente diligenciada, poniendo especial atención a los ratings y publico objetivo, así como a la descripción de la aplicación, el vínculo a la política de privacidad etc.

    6. Localización y Lenguaje

    • La localización y lenguaje de la aplicación debe ser establecido en el package.appmanifest. Ejemplo: si la app esta en español pero en el manifest dice EN-US será rechazada, puesto que esta cadena de localización indica que la App esta en inglés  y esto no es cierto.
    • Localización: La aplicación debe estar completamente localizada para los lenguajes que se hayan establecido en el package.appmanifest, esto incluye: textos y logos, screenshots etc. Si la aplicación va a nivel mundial se recomienda soportar 100% ingles.
    • Todo lenguaje soportado debe tener personalizados el 100% de los textos, imágenes etc. Localizaciones parciales son rechazadas automáticamente

    7. Política de Privacidad

    • Si la aplicación recopila información del usuario de alguna índole esta DEBE TENER una política de privacidad asociada

    Nota de WarNov: En realidad la condición no es recopilar info del usuario o no, sino el mero hecho de que en las capacidades de la app dentro del manifiesto de la misma, se especifica que la app se conecta a internet, como lo muestro en mi segunda anotación arriba.

    • Aunque la app no haga uso de ninguna información del usuario, se recomienda indicar eso en una política de privacidad sencilla.
    • La política de privacidad que se declara dentro del sitio web creado para la App, debe estar conforme a la estructura del sitio y no ser un archivo de texto nada más. La política debe ser descubrible por vínculos dentro del sitio.
    • Se recomienda que la política de privacidad sea accesible desde el Charm de configuración
    • Si se comparte información con terceros,  en el Charm de configuración junto con la política de privacidad se debe agregar una opción visible para autorizar o denegar ese uso de los datos.
    • Si el usuario no autoriza dicho uso la aplicación no debe perder toda funcionalidad, esto no es aceptado, la restricción de funcionalidad debe ser limitada.

     

    Muy bien, espero que puedan valerse de toda esta experiencia adquirida para minimizar la probabilidad de que sus apps sean devueltas tras un proceso de certificación fallido.

    Muchos éxitos!

  • WarNov Developer Evangelist

    Visual Studio 2012 Update 1 y la nueva interfaz del Package.appxmanifest

    • 0 Comments

    Tal como fue prometido, VS 2012 estará liberando updates frecuentes para mejorar rápidamente la experiencia que con esta herramienta tenemos como desarrolladores. Es el caso del update 1, que aparece solo pocas semanas tras el lanzamiento oficial. Es así como ya no tenemos que esperar a que aparezcan los pesados Service Pack que venían a ejecutar una serie de mejoras, pero con un alto costo de instalación.

    El Update de Visual Studio 2012 es detectado automáticamente por la herramienta y se instala desde ella misma. No hay que bajar nada manualmente. Es un proceso bastante sencillo.

    Hace solo un día, liberé la segunda versión de mi app PhotoRanker. Y una de las correcciones que le hice, fue incluir el ícono del logo para el store, pues anteriormente había olvidado hacerlo.

    Por qué lo olvidé? Fácil: Porque estando trabajando solo con Visual Studio en el editor del Package.appxmanifest que es donde encontramos el “wizard”para ajustar las imágenes requeridas para el store, en ningún lado nos pide esta imagen. Así que uno debe cambiarla manualmente, reemplazando el archivo StoreLogo.png que se encuentra dentro del folder de Assets. Esto es algo muy fácil de olvidar, claramente:

     

    oldpackagemanifest

    Qué tiene que ver esto con el update de Visual Studio 2012?

    Pues que entre muchas otras mejoras, el editor del Package.appxmanifest ha cambiado, incluyendo un manejador de imágenes mucho más avanzado y adecuado:

    NewPackageManifest

    Como se aprecia, aquí sí aparece el espacio para incluir el Store Logo de nuestra app. Así que ya no vamos a requerir un update solo para esto (cosa de la que yo fui victima). Pero por si fuera poco, además del nuevo orden que se le ha dado, podemos especificar también las tres escalas que manejamos en Windows 8 para poder presentar siempre imágenes de alta resolución sin importar el tamaño del dispositivo de presentación, tal como lo explico en este post.

    Es una gran mejora que facilita la vida a nosotros developers al momento de preparar nuestros paquetes de apps para certificar en el store.

    Otras mejoras incluidas en el update:

    • Code Analysis para apps de Windows Phone 8
    • Mejoramiento en el ALM para aplicaciones de SharePoint sobretodo en el campo de testing.
    • Mejoras para el trabajo en equipos ágiles en la administración de proyectos. Esto incluye soporte a Kanban; una herramienta para hacer tracking de proyectos.
    • La Calidad Continuada ha sido protagonista de mojoras también; por ejemplo con el update ya se puede ejecutar el code coverage en pruebas manuales de ASP.NET, sin mencionar que ya se puede ejecutar también grabado de pruebas en Internet Explorer, que después pueden reproducirse en los browsers modernos, para poder ejecutar pruebas cross-browsing.

    Si aún no te ha llegado el update y quieres aplicarlo ahora, puedes ejecutarlo desde aquí.

  • WarNov Developer Evangelist

    Escalado Automático de imágenes en Windows Store Apps

    • 0 Comments

    Las apps del Windows Store, a diferencia de las de cualquier otro Store de apps, ofrecen una gran versatilidad de presentación, pues pueden ejecutarse en diversos dispositivos que por ende presentarán diversos tamaños de pantalla.

    Por ejemplo, podemos ir desde netbooks de 1024x768, pasando a tablets como la Surface de 1366x768 y laptops o desktops de 1280x1024 y muchos intermedios hasta llegar a dispositivos HD como televisores a 1920x1200 y más.

    Entonces es lógico concluir que las imágenes que incluyamos en nuestras apps, no van a servir para todas las resoluciones. Deberíamos entonces generar todo programáticamente con vectores, cosa que no es sencilla aunque es posible y soportada en Windows 8.

    Cuál es entonces la solución?

    Igual recomiendo que comiencen a pensar en vectores. Cuando creen una imagen, háganlo en formato vectorial… olviden el dibujito jpg…. literalmente no escala y cuando escala se pixela. Recuerdan la premisa de que la app debe ser linda y así se debe ver en cualquier tipo de resolución? Pues bien; una de las grandes características de los gráficos vectoriales es que escalan muy bien y es fácil generarlos para varias resoluciones. Los gráficos vectoriales vienen en versiones como *.SVG que ya es un estándar. Y pueden exportarse fácilmente a los formatos convencionales. Además al igual que los *.PNG, soportan muy bien las transparencias. Desafortunadamente las apps como tal no soportan gráficos *.SVG. Siempre tenemos que pasarles las versiones *.PNG preferiblemente.

    Pero en ese caso, cómo se logra el escalado para cada tipo de resolución?

    image

    Muy sencillo. Windows 8 soporta que pongamos tres versiones de un mismo archivo, para que este pueda escalar adecuadamente. La idea es que cada archivo tenga una escala específica para cada tipo de monitor. En Windows 8 se han definido tres escalas. Normal (basada en una pantalla de 1366x768) o 100%, luego viene una mediana que es de 140% y finalmente la grande de 180% que soporta resoluciones HD sin distorsionar las imágenes. Y dependiendo de la resolución detectada, Windows 8 carga automáticamente el archivo adecuado. Nosotros solo lo referenciamos con la raíz del nombre y Windows 8 escoge el adecuado; otra opción es usar la convención de un folder por cada tipo de escala. Entonces al final implementaríamos de alguna de estas dos maneras:

    image

    En este caso, una imagen de 100x100 pixeles, tendría otras dos acompañantes: una de 140x140 y otra de 180x180.

    Como se aprecia, es un mecanismo bastante sencillo, ya que teniendo una imagen vectorial, podemos exportarla con las distintas resoluciones, incluirlas en nuestros assets y luego dejar que Windows 8 se encargue del trabajo sucio.

  • WarNov Developer Evangelist

    Concierto Gratis de Monsieur Periné para Apps Developers

    • 0 Comments

    Tal como lo leen.

    Así es, Monsieur Periné  Se llevará a cabo este miércoles 12 de diciembre en la Puerta Grande de Bogotá.

    Para desbloquear tu entrada a este evento, solo debes estar cursando alguno de los Bootcamps gratuitos de Apps.co: Windows 8 y Windows Phone. Si no estás registrado, aún hay tiempo. Hazlo aquí. aportar una idea de App para Windows 8 o para Windows Phone aquí y adicionalmente, aprovechar un taller de ideas que tendremos este día.

    Aquí les dejo una muestra de esta gran agrupación colombiana y nos vemos allí!

     

     

    Invitan Microsoft y el MinTIC con su programa APPS.CO

  • WarNov Developer Evangelist

    Async, Await y Task: for Dummies

    • 0 Comments

    Cuando queremos brindarle al usuario una experiencia rápida y fluida, lo más importante es no dejar que la interfaz se congele mientras se ejecuta alguna operación adicional, tal como cargar un archivo o conectarse a un servicio.

    En la antigüedad, esto se lograda con Threading, luego BackgroundWorkers y después TPL. Pero la evolución continuó para bien y hoy se logra a través de métodos asíncronos.

    Es un mecanismo por defecto del Framework 4.5 mediante el cual un método marcado como asíncrono, no congela la interfaz de usuario, pues por debajo empieza a correr en otro hilo distinto a aquel que hizo el llamado.

    Para marcar un método como asíncrono, le ponemos la palabra clave async antes del tipo de retorno del mismo.

    private async void ProcedimientoAsincrono()
    {
       for (int i = 0; i < 5; i++)
       {
           //Ejecutar subproceso i
    } }

    En este caso, el proceso  ejecuta todos los subprocesos, sin que la interfaz se congele, dado que ese es uno de los principales motivos de disgusto de los usuarios con las apps.

    Ilustración de un circuito contador asíncrono

     

    Sin embargo, dado que se inicia otro hilo de la app para ejecutar otro proceso… cuándo sabemos que este acaba? Cómo hacemos para proceder en consecuencia?

    Por ejemplo: Si queremos cargar tres páginas de contenido bajado de la web, necesitamos saber cuándo tenemos ya ese contenido en memoria antes de usarlo.

    En la antigüedad, teníamos siempre mecanismos de Callbacks a los que nos suscribíamos de manera que cuando el hilo nuevo terminaba lanzaba un evento y nosotros actuábamos en virtud a ello, asignándole un manejador. En lo personal, puedo decir que aunque es algo que funciona, no es muy natural, por el mismo hecho de que hay que agregar manejadores de eventos y demás.

    No sería más natural hacer el llamado al método y saber que cuando la ejecución pase a la siguiente línea es porque el método anterior ya se ejecutó y lo mejor de todo sin bloquear la interfaz?

    Bueno, para eso está la otra palabrita mágica protagonista de este post: await o sea, esperar. Si ponemos la palabra await antes del llamado a un método asíncrono, esto le dice al sistema que hasta que no acabe de ejecutarse el método llamado, la ejecución no puede avanzar hacia la siguiente línea. Lográndose entonces una ejecución natural sin tener que crear hilos ni objetos extraños e insisto: Sin bloquear la interfaz:

    await ProcedimientoAsincrono();
    SiguienteProcedimiento();

    Tengan muy en cuenta sin embargo, que no siempre vamos a querer este comportamiento.

    A veces por ejemplo requeriremos que se inicie el hilo y corra por su cuenta, mientras otra cosa pasa sin tener que esperar a que termine el procedimiento asíncrono. Por ejemplo, supongan que mientras cargan muchos datos, ponen una animación para entretener al usuario. En ese caso, lo que se debe hacer es lanzar el procedimiento asíncrono sin el await y luego lanzar la animación. De lo contrario, la animación solo comenzará a ejecutarse cuando el asíncrono haya terminado, lo que claramente no es nuestro objetivo. Así que es bueno tener una variable de finalización que sea actualizada por el método asíncrono. La animación entonces chequeará el valor de esta variable y solo se detendrá hasta que observe que la variable tiene el valor adecuado. Cuando este es nuestro objetivo, omitimos entonces el await en el llamado.

    Una vez entendidos los conceptos de async y await, pensemos en lo siguiente:

    Qué pasa si debemos llamar a un método que no fue creado como async?

    Nos veríamos obligados a usar threading o background workers? No. Ni siquiera tenemos acceso a ellos desde el perfil del Framework disponible en WinRT. En este caso, regresamos un poco al Framework 4.0 donde con TPL (Task Parallel Library) Tenemos acceso a la clase Task que nos permite de inmediato ejecutar un proceso en otro hilo; cosa muy útil, cuando este proceso no ha sido declarado como asíncrono.

    Entonces solo basta decirle a Task que ejecute el proceso que queremos:

    Task.Run(()=>ProcedimientoNoAsincrono());
    SiguienteProcedimiento();

    Como se observa, Task.Run recibe una Action, que no es más que una Lambda apuntando al procedimiento no asíncrono que existe en algún otro sitio. El procedimiento llamado por Task, también puede ser asíncrono, pero en este caso es más fácil llamarlo directamente, como vimos arriba.

    El llamado a Task también es susceptible a ser esperado usando await, así que obtenemos las mismas ventajas:
    No se bloque la interfaz y decidimos si trabajar en paralelo o de manera síncrona.

    En conclusión vimos qué nos ofrece el Framework .NET 4.5 para generar interfaces de usuario rápidas y fluidas. En el proceso, comprendimos sin muchas complicaciones para qué son y cómo se usan estos tres sujetos: async, await y task.

    Para ver async y await en acción, les dejo este post, donde capturamos imágenes desde la cámara de un dispositivo con Windows 8.


    asincronía, asincrónico, paralelo, hilos, threads, background, fluido, interfaz fluida, fast, framework 4.5, Windows 8,  metro style, apps, winRT, WindowsRT

  • WarNov Developer Evangelist

    PhotoRanker: Making of a WinRT App

    • 0 Comments

    Este es un post en el que quiero compartirles la experiencia de publicar una app en el store de Windows 8 desde el punto de vista de un desarrollador estándar que ha sufrido en el proceso y ha dejado huella de sus heridas en el código que escribió… mostraré no solo los aspectos técnicos que se tuvieron que superar, sino también los procedimientos de publicación requeridos por el store. Tengan en cuenta sin embargo, que esta no es una guía que enseña a desarrollar apps y que parto del hecho de que ya se sabe como tener una cuenta en el Windows Store, pues tampoco explico cómo se abre una de ellas aquí.

    Objetivo

    PhotoRanker es una app con un único y claro objetivo… como todas las apps deberían ser. El objetivo es poner rating a las fotografías (estrellas) de una forma rápida y eficiente. De esa manera sabes cuáles realmente merecen ser editadas y cuales otras no valen ni un centavo y mejor borrarlas de una.

    Una app debe tener claro su objetivo, para poder de esa manera ser clara en su implementación y clara en su uso. Estamos en un mundo de cientos de miles de apps. En este mundo cada app solo tiene una oportunidad. Si no es buena a primera vista, lo más probable es que genere una desinstalación inmediata. De hecho, personalmente me he visto haciendo eso como consumidor de apps que soy. Así que si no encuentro de inmediato cómo manejar la app, me frustro y le doy uninstall… suerte es que le digo.

    Release Often, Release Fast

    Otra ventaja de tener bien claro el objetivo, es que tu app va a salir rápido al store. No van a pasar eones mientras por fin terminas de implementar las toneladas de funcionalidad que pueden ir pegadas a una app. De hecho, esta app me consumió 9 horas de desarrollo incluyendo dificultades técnicas, ya que no es un simple RSS. Lo importante, es que pude salir al aire pronto con mi app. Esta nueva tendencia de la industria nos lleva al famoso: “Release often. Release fast”. Naturalmente, cuando publicamos nuestra app con su funcionalidad principal claramente establecida, es fácil comenzar a ver los puntos de mejora y extensión para liberar nuevas versiones. Anyway el update de una app no vale nada… solo es necesario subir la nueva versión y por experiencia os digo, que la liberación de un update tarda mucho menos que la del estreno de la app. Además como usuario, uno se siente muy agradado de recibir updates de las apps que usa, pues solo la mera curiosidad de ver qué mejoró, me hace entrar de nuevo a la app. Sentimos entonces como usuarios que el developer está pendiente de la app y que cada vez encontraremos mejoras en ellas; al final esto se ve representado en buenos rating, mercadeo viral y por ende, más descargas.

    Diseño

    Tal vez este sea el requisito más trillado en el tema de apps. Si una app es fea, le va pasando algo parecido a cuando es difícil de manejar: produce frustración y el peor de los males desinstalación, acompañado tal vez de un @#$%^&*( en los reviews, que para nada nos favorece. Para Windows 8 hay muchas guías de diseño. Tener un amigo o socio o equipo diseñador, es lo más recomendado. Pero si somos Hard Die Alone Developers, tal vez tengamos que desarrollar ciertos skills de diseño, para hacer toda la app por nuestra propia cuenta; o al menos los bosquejos de la misma. Para este proceso además de alguito de talento, necesitaremos algunas tools que nos facilitarán la vida.

    Entonces es cuando recomiendo que comiencen a pensar en vectores. Olviden el dibujito jpg…. literalmente no escala y cuando escala se pixela. Recuerdan la premisa de que la app debe ser linda y así se debe ver en cualquier tipo de resolución? Pues bien; una de las grandes características de los gráficos vectoriales es que escalan muy bien y es fácil generarlos para varias resoluciones. Los gráficos vectoriales vienen en versiones como *.SVG que ya es un estándar. Y pueden exportarse fácilmente a los formatos convencionales. Además al igual que los *.PNG, soportan muy bien las transparencias. Desafortunadamente las apps como tal no soportan gráficos *.SVG. Siempre tenemos que pasarles las versiones *.PNG preferiblemente.

    Pero en ese caso, cómo se logra el escalado para cada tipo de resolución?

    Muy sencillo. Windows 8 soporta que pongamos varias versiones de un mismo archivo de imagen en la carpeta en donde los estemos almacenando. La idea es que cada archivo tenga una escala específica para cada tipo de monitor. En Windows 8 se han definido varias escalas. Normal (basada en una pantalla de 1366x768) o 100%, luego viene una mediana que es de 140% y finalmente la grande de 180% que soporta resoluciones HD sin distorsionar las imágenes. Y dependiendo de la resolución detectada, Windows 8 carga automáticamente el archivo adecuado. Nosotros solo lo referenciamos con la raíz del nombre y Windows 8 escoge el adecuado; otra opción es usar la convención de un folder por cada tipo de escala. Entonces al final implementaríamos de alguna de estas dos maneras:

    image

     

    Supongan entonces que se han bajado Visual Studio Express for Windows 8 que es totalmente gratuito y permite comercializar sin problemas las apps que con éste diseñemos. Pues bien… si pagamos 0 por esa herramienta, deberíamos de pagar un montón por una buena herramienta de dibujo y manejo vectorial? Hacerla de piratas y arriesgar nuestra máquina a que se llene de malware tratando de bajar una versión pirata de dicho editor gráfico? Por supuesto que no! Así que en este punto me permito recomendar una gran herramienta free y OSS llamada Inkscape. Con capacidades similares a las de Illustrator, es de manejo muy sencillo y da productividad rápida. La verdad es que yo no sabía mucho de edición de vectores, pero en poco tiempo ya estaba cómodo con la interfaz que me permite manejar capas, hacer operaciones entre objetos (adicionarlos, sustraerlos, intersectarlos), exportar y muchas cosas más. Efectivamente con esa herramienta junto con Paint.Net una tool free creada con .NET y que podría definir como un mspaint con esteroides o PhotoShop light que permite ya manejar los mapas de bits finales (no vectoriales), generé todo el arte requerido para el store de Windows 8, cuando subía a certificación PhotoRanker.

    SiteHeader

    Logo

    entre otras…

    The Store

    Ya que hablamos del arte requerido para el store, algunos puntos al respecto:

    Primero, podría mencionar que es muy fácil ejecutar el proceso de publicación una vez se ha terminado la app. Existe un archivo dentro del proyecto de nuestra app que contiene toda la información relevante con este fin. Ese archivo es el Package.appxmanifest. Visual Studio provee un amigable editor para configurar este archivo antes de subirlo al store. En este, podemos por ejemplo especificar las imágenes de arte a usar para que nuestra app se liste gráficamente en el store, para los tiles, las capacidades de los dispositivos que la app requerirá y muchos otros más.

    oldpackagemanifest

    Vemos allí como se nos piden los diversos archivos de arte y otra metadata para el store. De aquí quiero hacer la primera salvedad. En este diálogo no se nos pide un logo para el store. Así que si no hacemos algo al respecto, nos aparecerá nuestra app con un horrible logo con una X dentro de un cuadrado. Créanlo… a mí me pasó…

    image

    Y así quedará publicada nuestra app. Para corregir esto, lo que debemos hacer es cambiar la imagen existente en Assets\StoreLogo.png, por la imagen personalizada que generalmente es un PNG de 50x50: (tuve que lanzar una nueva versión al store solo por esto)

    StoreLogo

    Afortunadamente, acabo de notar que tras la instalación del Update 1 de Visual Studio 2012, esta situación mejoró sustancialmente al proveerse un nuevo diálogo para este archivo, que permite hasta especificar las imágenes de arte en distinta escala:

    NewPackageManifest

    Vean más detalles en este post.

    Existen muchas otras condiciones para tener en cuenta en la publicación, como las que enumero en este post. Pero luego las leen. Por ahora continuemos con la experiencia en general.

    Versiones y Apps Huérfanas:

    Son ustedes padres desalmados? Por favor  no dejen huérfanas sus apps. No se trata de subirlas y dejarlas en el store sin nadie que las mantenga. Cada minuto que empleen ustedes en hacer una app, es un potencial minuto que puede traerles retorno de la inversión… ganancia. Si dejan su app sin mantener, están desperdiciando esos minutos que invirtieron previamente.

    Pídale a sus amigos que le den opiniones de la app. Qué cosas ven que estaría bien que incluyeran. Ustedes mismos pueden tener sus propias ideas. Comiencen implementando una por una… o si está muy fácil, suban un grupo de tres nuevos features. El Store facilita mucho el proceso. Entre otras cosas, pide que pongan los detalles de las novedades  de la versión.

    Personalmente, le cree un portal a mi app. Lo creé gratuitamente en Windows Azure a través de Windows Azure Websites. En este sitio web, puse una sección de Version History, en la cual muestro la evolución de mi app en cada versión. Esto me permite mostrar que la app está en continua evolución… esto obviamente fideliza a mis actuales usuarios y me trae nuevos. Imaginen que están vendiendo ads publicitarios en sus apps (sé de apps de desarrolladores independientes que han llegado a hacer USD$100.000 en solo ads); en ese caso hay que hacer todo lo posible por que permanezcan con nuestra app. Precisamente esto me lleva al otro punto de este post.

    Cuida tu código:

    Siendo el desarrollador independiente de hoy, querrás estar en permanente movilidad y que el código que hagas vaya contigo a todo lado. Que esté actualizado y que además puedas manejar versionamiento de una manera bastante cómoda…. correcto, te estoy hablando de tener un administrador de código fuente… y sí en Microsoft también ofrecemos un manejador gratuito: Team Foundation Server Express, que gratuitamente les soporta hasta 5 developers. Se lo pueden bajar e instalar, pero yo prefiero usar la versión online que me evita la fatiga de la instalación y me permite tenerlo everywhere. Solo hay que registrarse aquí. Luego de esto, solo queda hacer checkins, checkouts y terminar nuestra app.

    Cuida tus clientes:

    Efectivamente si queremos que nuestra app nos dé ganancia, hay que dar un valor agregado a los usuarios. Por esto es bueno tener un portal dedicado a nuestra app en el que podamos tener flexibilidad para acompañarla con información adicional, avisos, y demás. Una vez tengamos el portal, obviamente es requerido que dentro de nuestra app le demos la posibilidad al usuario de saber que este portal existe y obviamente de acceder al mismo. Un sitio adecuado para esto, es en el About, dentro del charm de settings de la app. No lo vayan a poner grandote en todas las páginas de su app, porque eso no es nice. En el peor de los casos, al menos háganle una página en FB. Es gratis y sirve para enganchar conversaciones que le dan buzz a tu app. Aprovecha los logos oficiales del Windows Store que encuentras aquí para poner el link a tu app en el store (te llega por correo una vez es aprobada; te recomiendo que de una vez le saques un short url pues es complejo) y por favor sigue las reglas de uso de esos logos que están ahí no los vayas a deformar, recortar ni adornar con maripositas.

    Explota la plataforma

    Windows 8 tiene una gran cantidad de features para enamorar al usuario. Es un total desperdicio entonces terminar haciendo apenas una app lectora de rss que no tiene en cuentas estos features. En la creación de PhotoRanker he tratado de incluir la mayor cantidad de features de Windows 8 que tenga sentido para este tipo de app. Algo muy válido eso sí, es que la primera versión salga muy sencilla, pero luego le vamos agregando estos features que realmente harán que nuestros usuarios se sientan muy agradado de usar nuestra app. Por ejemplo, en mi primera versión no soportaba portrait ni snap view mode. Tampoco guardaba settings de la app. Pero ya en la tercera, todo esto está soportado. Y por supuesto la idea es en futuras versiones incorporar más features. Por ejemplo un live tile que muestre fotografías rankeadas con 5 estrellas, la posibilidad de buscar fotografías por número de estrellas usando el charm de search y usar el charm de share para compartir determinada fotografía.

    Modos de presentación:

    Las apps de Windows 8 tienen 3 modos de presentación principales: Full o Landscape, Snap y Portrait. La utilidad de Snap hace mucho sentido en esta app, pues es bien viable que uno por ejemplo esté rankeando sus imágenes mientras ve por ejemplo un video al mismo tiempo. En Windows 8 la mayoría del trabajo de presentación en Snap View se hace automáticamente, pero casi siempre quedan pequeños detalles por corregir. Por ejemplo, en mi app cuando está en fullscreen mode, la fotografía se centra verticalmente:

    image

    Pero al pasar a Snap, si dejo el comportamiento automático, la imagen se reduce también y al ser pequeña, se ve muy afectada por la superposición de las estrellas:

     

    image

    La imagen queda perdida en el control.

    En este caso algunos ajustes adicionales al modo snap son requeridos. Es muy fácil ejecutarlos una vez identificamos el sitio donde se maneja este evento de cambio de posicionamiento:

    public void OnSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs args)
    {
    switch (ApplicationView.Value)
    {
    case ApplicationViewState.FullScreenLandscape:
    VisualStateManager.GoToState(this, "Full", false);
    break;
    case ApplicationViewState.Snapped:
    VisualStateManager.GoToState(this, "Snapped", false);
    break;
    case ApplicationViewState.FullScreenPortrait:
    VisualStateManager.GoToState(this, "Portrait", false);
    break;
    default:
    break;
    }
    }

    Como se observa, solo basta interceptar el evento de OnSizeChanged y luego con un sencillo case actuar de acuerdo al cambio experimentado. En este caso, para corregir el pequeño error del snap view, lo que hago es en el respectivo case, cambiar la alineación vertical de la imagen, y ponerla en TOP:

    image

    Ese pequeño cambio que hice, significa una mejora sustancial en la experiencia del usuario, ya que aprovecho mejor el espacio y la imagen se ve completamente despejada. Además noten cómo dejo los controles abajo, de manera que ergonómicamente hablando, están muy accesibles para el usuario. Un inconveniente que experimenté en la vista de Snap View,  fue a través del uso del folder picker cuando está en esta vista. Sucede que si abrimos un folder picker y la app está en snap view, se genera una excepción, porque el folder picker no puede trabajar en este modo. Es por esto que con código debemos obligar a la app a expandirse antes de abrir el folder picker. En este post explico cómo hacerlo.

    Del portrait mode puedo mencionarles que no requirió ningún ajuste porque la auto organización que da WinRT ya es suficiente:

    image

    Pero sí quiero hacer una salvedad y es que no olviden además de manejar el código requerido para portrait dentro del manejador del evento OnSizeChanged, especificar en el Package.appxmanifest que la app soporta portrait mode (yo lo olvidé porque creí que con sólo escribir el código bastaba):

    image

    También les cuento que acabo de notar que aunque controlo muy bien el comportamiento de la ventana principal (donde manipulo las imágenes) en las distintas presentaciones, olvidé controlar la presentación de la primera pantalla en Portrait y Snap, así que se ve algo desquiciado en estos momentos (pruébenlo por ustedes mismos y observen qué cosas deberían corregirse; traten de pensar cómo lo harían). Para la versión 4 estaré corrigiendo esto y agregando un par de funcionalidades más.

    Manejo de Estados:

    Como novedad para la versión 3 de PhotoRanker, incluí que la app recordará en que foto íbamos. De manera que si el usuario se sale de la app o la cierra, cuando vuelva a abrirla, tenga la posibilidad de escoger si arranca desde donde estaba la última vez:

    image

    Como ven, tengo un botón destinado para esto. Así el usuario decide si arranca un trabajo nuevo o continúa con el último que estaba haciendo. Esto es muy útil, pues en realidad le da mucha agilidad a la app. En otros escenarios, no es tan lógico preguntar si se quiere arrancar desde el último estado, sino que de inmediato cuando se vuelve a abrir la app, pasamos a este estado. Aquí en mi app sin embargo, sí quise dar la opción. Otros asuntos que guardo, es por ejemplo la elección del usuario de hacer auto-advance mientras hace rating a las fotos. Esta opción de auto-advance, permite que tan pronto el usuario hace tap sobre una estrella para calificar, la siguiente foto sea cargada inmediata y automáticamente, para agilizar así aún más el proceso. Así pues, el valor de esta opción queda almacenado y la app siempre lo recuerda y usa, hasta que el usuario cambie dicho valor.

    El proceso de almacenamiento de settings y valores de variables es supremamente sencillo:

    Windows.Storage.ApplicationData.Current.
    LocalSettings.Values["AutoAdvance"] = true; Windows.Storage.ApplicationData.Current.
    LocalSettings.Values["LastIndex"] = 45;

    Y recuperar los valores es exactamente igual, eso sí haciendo el respectivo Convert, dado que los valores son almacenados como objetos.

    Splash  Screen Animado

    Una muy buena forma de arrancar impactando con nuestra app, es extendiendo el splash screen para que no sea una simple imagen estática, sino que podemos agregar una animación que “entretenga” al usuario mientras ejecutamos por ejemplo algunas cargas iniciales.

    Por naturaleza el Splash Screen de WinRT no se puede animar. Lo que sí se puede hacer, es una simulación de animación, ubicando una nueva página que inicialmente se vea exactamente igual al Splash Screen y luego allí haciendo las animaciones requeridas.

    Esto es fácil de lograr comprendiendo el mecanismo.

    Sucede que cuando la app arranca, se dispara un evento llamado OnLaunched en el App.xaml.cs. Ese evento trae unos argumentos args. Y dentro de estos argumentos, viene una referencia al SplashScreen que no es más que la imagen que especificamos en el manifiesto de la app para serlo.

    Este objeto splash screen tiene entre otros atributos, un rectángulo llamado ImageLocation que determina exactamente las coordenadas en las que se encuentra la imagen que hemos escogido para mostrar. Obviamente, la importancia de este rectángulo radica en que basados en sus coordenadas, ubicaremos la imagen en una nueva página que es donde ejecutaremos la animación:

     


    var splashImageRect = splash.ImageLocation;
    extendedSplashImage
    .SetValue(Canvas.LeftProperty, splashImageRect.X);
    extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
    extendedSplashImage.Height = splashImageRect.Height;
    extendedSplashImage.Width = splashImageRect.Width;

    De esta manera obtenemos una página idéntica al Splash Screen, sobre la cual ejecutaremos una animación mientras hacemos la carga inicial.

    Asincronía

    Y ya que mencioné animaciones mientras se carga “algo”, de inmediato se me viene a la mente la asincronía. Porque efectivamente estoy hablando de un hecho en el cual asíncronamente se muestra una animación mientras se cargan elementos en memoria por ejemplo. Todo esto sin bloquear la interfaz del usuario, para que éste no sienta que la app es un ladrillo lento y no se aburra… y no desinstale… y recomiende. Es por esto que la asincronía es tan importante en las apps de WinRT. Es un mecanismo súper importante para lograr apps Fast and Fluid. Premisa número 1 de las Windows Store Apps. Sin ella, la interfaz se congelaría a menos de que usaramos complejos procesos con threads y demás.

    Precisamente para aprovechar el splash screen y cargar los settings del usuario, lo que hago es generar una animación, mientras en otro hilo a través de un método asíncrono inicio la ejecución del proceso de carga de una manera muy sencilla.

    Para comprender mejor este tema, les recomiendo este post, donde explico de una manera bien elemental éste proceso.

    De manera similar resuelvo situaciones en las que la app debe tomarse su tiempo, para que el usuario siempre sienta que la app le responde adecuadamente (por ejemplo cuando se lee el directorio con las fotos que se van a rankear)

    Conclusiones

    He tratado en este artículo de mostrar de una manera bastante informal, las principales experiencias que he tenido publicando una app con cierto nivel de complejidad en el Windows Store. La idea es que ustedes se puedan llevar algo de este conocimiento y que además les sirva para tener nuevas ideas a implementar en sus apps.

    Espero a medida de que mi app va evolucionando, ir escribiendo continuaciones a este post que sirvan para enriquecer el conocimiento de la comunidad en cuanto a apps se refiere.

    Las apps, a diferencia de otros tipos de desarrollo, son individualizadas con un dueño perfectamente identificado… por eso afirmo que una app es un hijo digital del developer… es su descendencia.

    Procuremos tener una descendencia remarcable. Sonrisa

  • WarNov Developer Evangelist

    Cómo seleccionar automáticamente un elemento dentro de un Panorama

    • 0 Comments

    Dice el corresponsal:

    “Hola Walter, como hago en una App WP8 para navegar a una pagina con control panorama y abrir inmediatamente un index diferente a 0. es que tengo un menú y según seleccionen abrir la pagina que tiene el panorama pero el ítem seleccionado. Gracias”

    R./ Suponiendo que tenemos una página inicial con un botón que hace la transferencia a una segunda página panorama, podemos agregarle al llamado de la segunda página un parámetro que nos indique el ítem que deseamos en el panorama:

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
         NavigationService.Navigate(new Uri
    ("/PanoramaPage1.xaml?item=2",UriKind.Relative)); }

    Luego solo basta manejar el evento OnNavigated de la página de destino, en la cual debemos de haberle dado un nombre al panorama para poderlo referenciar y luego ajustarle el ítem por defecto para cuando se abra la página:

     

    override protected void OnNavigatedTo(NavigationEventArgs e)
    {
        var item = int.Parse(NavigationContext.QueryString["item"]);
        pnrControl.DefaultItem=pnrControl.Items[item];
        base.OnNavigatedTo(e);
    }
    

    y voilà!

    image

  • WarNov Developer Evangelist

    No confundir el idioma de tu app, con los países en los que se verá

    • 0 Comments

    Las apps para el Windows Store y Windows Phone Store, manejan un lenguaje por defecto que se encuentra en el manifiesto de cada una de ellas.

    Este lenguaje se ajusta de acuerdo al lenguaje de la máquina del desarrollador. Por ejemplo si el desarrollador tiene su máquina ajustada a Inglés de Estados Unidos, este será el lenguaje por defecto de la app.

    Sin embargo, este lenguaje es configurable; pero al encontrarse en una ubicación no muy visible, puede pasar que no lo observemos y luego pasemos al proceso de publicación dejando un lenguaje por defecto incorrecto, porque puede que haya quedado en Inglés y nuestra app vaya solo en español.

    Cuando pasamos al proceso de publicación en ambos store nos piden los idiomas en los que está disponible nuestra app. También nos piden los países en los que queremos visible nuestra app.

    Ojo que son cosas distintas que no deben confundirse: Uno como developer puede poner su app visible en diversos países, independientemente del o de los idiomas que esté exponiendo. Hay developers que piensan que dado que nuestra app solo expone español, entonces no puede ponerse en mercados que no hablan español, pero esto no es así. Lamentablemente este hecho nos puede quitar oportunidades de darle visibilidad a nuestra app al ponerla en varios países, tal como lo describo en este post.

    Por ejemplo yo como developer colombiano puedo poner mi app visible en Colombia, Estados Unidos e Inglaterra, habiéndola publicado solo en español. Y esto es válido y la app puede ser publicada sin ningún problema.

    Sin embargo observen este hecho curioso: Supongan que escogemos Español. Y que agregamos todos los recursos e imágenes en español necesarias para este fin. Además que pusimos nuestra app disponible en todo el mundo.

    Pero luego de un tiempo nos llega el rechazo de la app porque dizque no subimos los recursos necesarios para los lenguajes especificados. Será porque escogimos países que no hablan español?

    Como lo expliqué anteriormente, este no es el motivo.

    Por qué pasa esto?

    Como les comenté al principio, dado que las apps además quedaron con lenguaje por defecto Inglés Estados Unidos, pues el store espera que subamos esos recursos también.

    Así que la forma de solucionar este problema es modificar estos lenguajes y culturas por defecto, antes de subir la app al respectivo  store.

    En el caso de Windows Phone, esta información se encuentra en las propiedades de la app. Así que abriendo el cuadro de diálogo propiedades desde el explorador de soluciones dando click derecho obtenemos el editor de propiedades. Allí escogemos la información del assembly y allí modificamos el valor. En este ejemplo vemos como estamos cambiando desde Inglés Estados Unidos a Español Colombia:

    image

    En Windows 8, esta información se configura desde el editor del Package.appxmanifest (doble click al archivo con este nombre para abrir el editor):

    image

     

    Aquí solo basta corregir “en-US” por es o por ejemplo “es-CO”.

    Y listo!

    De esta manera ya le estamos diciendo al store que no espere recursos de Inglés Estados Unidos, porque ahora la cultura por defecto es el Español.

    Conclusión: No se confundan si su app es rechazada por motivos de idioma. Esto no tiene nada que ver con los países de publicación elegidos, sino con la cultura por defecto que viene configurada cuando ustedes arrancan a desarrollar una app.

Page 1 of 1 (9 items)