Scala desde la perspectiva de C# y JavaScript, desde la Mindcamp

Este fin de semana he tenido la oportunidad de dar una charla en la Mindcamp sobre las características de Scala que he ido aprendiendo durante estas últimas semanas.

Aunque queda aún mucho por aprender, esta charla resume los temas que hemos ido viendo en los artículos anteriores de esta serie, así como algunos ejemplos donde podemos ver:

  • Hola mundo y diferencias de sintaxis con Java o C#
  • Clases, objetos, y funciones como ciudadanos de primera clase.
  • Sintaxis iterativa VS Sintaxis funcional.
  • Traits como manera de tener interfaces con implementación.
  • Case classes para realizar pattern matching y separar la interfaz de la implementación.

Los ejemplos están disponibles en este repositorio de Github: Mindcamp7-Scala.

Como parte de la charla, puse una lista de una serie de características que se quedaron fuera y que quedan como idea para futuros artículos, como son:

  • Frameworks como Play y Scalaz
  • Testing con ScalaTest
  • Integración con herramientas
  • La línea de comandos (REPL) de Scala
  • Interoperabilidad con Java.
  • La herramienta Activator de Typesafe
  • Scala Build Tool

Además, algunos recursos, muchos de los cuales ya hemos listado anteriormente en el blog, como son:

Finalmente, un par de libros que me recomendó el gran Jorge Barroso (@flipper83) sobre programación funcional:

Las diapositivas están disponibles en mi SlideShare: Scala desde C# y JavaScript

La semana próxima estaré en la LambdaWorld, un evento que reúne en Cadiz a lo mejor de la programación funcional, y habrá, por supuesto, Scala. Nos vemos allí!

Probando AppNow, lo nuevo de los chicos de Icinetic

Disclaimer: Aunque conozco personalmente a miembros del equipo de AppNow (unos auténticos cracks) no tengo ninguna relación con la empresa ni con los productos que ella desarrolla.

TL; DR Los creadores de Radarc acaban de lanzar la preview gratuita de AppNow, una herramienta en la nube para generar un backend para nuestras aplicaciones. En este artículo veremos cómo generar nuestro backend, el resultado, y qué nos podemos encontrar en el código generado.

contents

Un poco de contexto

Si no sabes qué es Icinetic, es una empresa con sede en Sevilla que se dedica al desarrollo de productos y aplicaciones móviles. Su producto estrella, Radarc, es una una solución para generar modelos de aplicaciones nativas a partir de un modelo de clases (model-driven design).

Su funcionamiento se realiza a través de diversos módulos llamados fórmulas y se integran en Visual Studio a través de una extensión. Pude verlo en acción hace unos meses y me quedé muy impresionado con la calidad del código generado.

En el pasado /Build, saltaron a la nube presentando Radarc Online, lo que supone una independencia de Visual Studio, y hoy han ido un paso más allá con AppNow, una herramienta para crear y desplegar backends personalizados en la nube.

Características técnicas y limitaciones

La versión beta nos permite probar un stack MEAN, es decir:

  • Servidor: Heroku
  • Base de datos: MongoDB
  • Backend: Node.js + Express.js
  • Frontend: Angular.js

Primer contacto

Cuando entramos a la web lo primero que podemos hacer es iniciar sesión con nuestra cuenta de nuestra red social favorita:

appnow_home

El siguiente paso es configurar nuestro modelo de datos, que para este ejemplo he optado por cargar el conjunto que ofrecen por defecto:

datamodel

Una vez configurado el modelo de datos, continuamos con nuestras credenciales de heroku. En este punto es muy importante que nuestra credencial esté validada (ver más..) y que agreguemos nuestra clave SSH a Heroku para poder continuar.

heroku

Si todo ha ido bien podremos ver una pantalla como la que se muestra, que se irá actualizando mientras se va generando la solución.

generated

Con ello hemos generado código a partir de nuestro modelo de clases, y lo hemos desplegado en la nube con un solo paso. El resultado de dicho despliegue es este sitio:

result

Desde él podemos listar los modelos creados, así como agregar, editar y borrar los mismos.

Bajo el capó

contents

En la lista de ficheros podemos ver, dentro del directorio public las diferentes vistas, controladores y servicios que forman parte de una aplicación angular, y por otro el backend dentro del directorio app.

Si echamos un vistazo al código podremos ver algunos detalles:

  • El acceso a MongoDB se realiza mediante mongoose, que es un ORM que nos aporta validación y tipos estrictos de datos para trabajar con MongoDB,
  • La API (generada usando Express.js) es compatible con swagger, que si no lo conoces, es una herramienta que nos permite generar documentación así como clientes estáticos y dinámicos de manera automática a partir de los comentarios de la API
  • La aplicación Angular es una SPA, con un controlador por cada entidad que hemos especificado al principio, y diferentes acciones de edición, agregación, listado o borrado para cada uno de ellos.
  • Soporta, adicionalmente, autenticación y sesiones a través de servicios de Angular.

Conclusiones

Un punto interesante en este aspecto es que ofrece el paquete completo, no solamente la generación de código sino que también el despliegue, y, al estar basado en git, podemos, a partir de ese momento, obtener el control del código y continuar el desarrollo. Es una manera simple y elegante de crear un servicio de backend, que, una vez generado, no tiene ninguna dependencia adicional a servicios de Radarc.

Aunque no es más que una demo, es una prueba interesante de la potencia tras esta herramienta. El código que genera es limpio, bien comentado, a partir del cual se podría continuar el desarrollo (nada que ver con el código auto-generado que hemos visto en algunas herramientas). Mi recomendación es probarlo con paciencia, y avisar a los chicos de Icinetic si encontramos algún fallo. Sin duda, un proyecto a seguir de cerca!

Enlaces

5 puntos a tener en cuenta al migrar apps a Windows Phone 8

El pasado 5 de octubre, en el evento #wpdevweek, en una de las charlas, vimos los cambios a los que nos podemos enfrentar cuando migramos una app de Windows Phone 7 a Windows Phone 8. Este artículo comenta, a modo de resumen, los 5 puntos que más dieron que hablar.

Migrando una app: El proceso corto

Salvo sorpresas, el proceso de migración de una app de WP7 a WP8 es tan sencillo como ir a nuestro proyecto y hacer click en «Upgrade to Windows Phone 8.0» como se muestra en la imagen:

upgradeButton

Tras la actualización, podemos ver los siguientes cambios:

  • Los ensamblados cambian, pasando de media docena a tan solo tres.
  • El WMAppManifest, que contiene la información de nuestra app, cambia para soportar las nuevas característcas, resoluciones, capacidades, y requisitos.

Por lo demás, la aplicación se mantiene exactamente igual, y si la ejecutamos en nuevo emulador veremos que se comporta de igual manera.

1. El emulador

Lo primero que necesitamos saber del emulador de WP8, es que los requisitos mínimos cambian, ya que ahora la emulación se hace por hardware, utilizando Hyper-V, el sistema de virtualización que lleva usando Microsoft en sus servidores la última media década.

La principal novedad del mismo es que ahora cargamos una edición completa del sistema operativo móvil, con todas las aplicaciones disponibles tal cual nos encontramos un Windows Phone de fábrica. Además podremos emular las nuevas resoluciones de WP8 y dos configuraciones de memoria, una con un límite de 512 MB de RAM, y otra sin este límite.

Para poder ejecutar el emulador necesitaremos un procesador que soporte SLAT (Second Level Address Translation), es decir, cualquier ordenador con un núcleo i3, i5 o i7 de Intel nos valdrá. Si nuestro sistema no soporta el emulador, podemos recurrir a http://developer.nokia.com/Devices/Remote_device_access/ que nos permite probar nuestras aplicaciones de manera remota.

2. Resolución

Otra de las novedades que nos afectan es que tenemos 2 resoluciones más de las que preocuparnos, a la WVGA (480 x 800) se suman las siguientes:

  • WXGA (768 x 1280)
  • 720p (720 x 1280)

La primera conserva la relación de aspecto, pero la segunda la cambia, con lo cual tendremos que ser capaces de detectar este cambio de resolución y actuar en consecuencia. Para ello en MSDN nos proporcionan un código de ejemplo, que se resume en el valor de:

App.Current.Host.Content.ScaleFactor
  • Si este valor es 100, estamos ante WVGA
  • Si el valor es 160, estamos ante WXGA
  • Finalmente, si es 150, tenemos un teléfono con resolución 720p

3. Modelo asíncrono

El modelo asíncrono de WP8 es el mismo que en Windows 8, usando los modificadores async y await, evitando el uso de callbacks que puedan complicar la lógica de nuestra aplicación. Comparemos un proceso síncrono (por tanto bloqueante, y que no debemos permitir):

LongTaskHelper helper = new LongTaskHelper();
helper.RunSync();
sync.Content = "Recibido " + DateTime.Now;

Con la manera de hacer procesos asíncronos hasta ahora, usando callbacks:

LongTaskHelper helper = new LongTaskHelper();
helper.TaskFinished += helper_TaskFinished;
helper.StartRun();
...
callbacks.Dispatcher.BeginInvoke(() =>
{
    callbacks.Content = "Recibido " + DateTime.Now;
});

Hasta finalmente, el mismo proceso usando async/await:

LongTaskHelper helper = new LongTaskHelper();
await helper.RunAsync();
async.Content = "Recibido " + DateTime.Now;

Este modelo nos permite aprovechar la sencillez de la programación síncrona, y la versatilidad de la programación asíncrona. Además, lo podemos usar para Windows 8 y en general con .NET Framework 4.5

4. XNA ha muerto, alternativas

Para aplicaciones WP8 no se permite el uso de XNA, aunque se pueden hacer proyectos WP7 que funcionarán bien en WP8, pero no podremos usar las nuevas características, como el acceso a la wallet, la cámara frontal y el sensor NFC, entre otros.

La alternativa que propone Microsoft es usar DirectX / Direct3D para el desarrollo de juegos, y la comunidad propone el uso de MonoGame, la implementación open-source multiplataforma de XNA.

5. Manteniendo compatibilidad

Existen varias maneras de mantener compatibilidad entre varias aplicaciones WP7 y WP8:

  • Usando enlace de archivos (cuando agregas un fichero existente a un proyecto en Visual Studio, lo puedes agregar como copia o como enlace).
  • Usando compilación condicional, podremos saber si estamos en WP8 con la directiva #ifdef NETFX
  • Usando una Portable Portable Class Library, un componente que es compatible con plataformas como Xbox, WP7, WP8, Windows 8 o .NET Framework 4.5. De esta manera, y usando patrones como MVVM, podemos mantener la lógica en un único punto.

Conclusiones

La migración de WP7 a WP8 puede causar algunos problemas, debido a que hay APIs que cambian, y hay más cosas a tener en cuenta. Por otro lado el mercado va creciendo (un 238% el pasado año) y las nuevas características de los terminales nos pueden dar más capacidades a nuestras apps.

Merges un poco más inteligentes para C#

Las operaciones de merge son muy comunes en los sistemas de control de versiones distribuidos, y si hay muchos cambios a nivel de pocos ficheros (equipos trabajando en una misma funcionalidad) podemos tener muchos conflictos. Para ayudar a mejorar la productividad en estas operaciones ayer hemos anunciado la disponibilidad a todo el público de la beta de SemanticMerge.

La idea es simplificar la resolución del conflicto entendiendo el código, resolviendo de manera automática aquellos en los que sea posible y permitir al usuario, de manera sencilla, encargarse de los conflictos restantes. En este artículo veremos de un vistazo la herramienta sus características, los casos que cubrimos y cómo la hemos desarrollado.

Una interfaz sencilla

La herramienta, formada básicamente por un panel donde se muestran los conflictos y diferencias, y un visor de código, permite por una parte resolver conflictos, y por otra ver en detalle los cambios sucedidos en cada fichero respecto a la base.

Para ayudar al usuario, cada conflicto tiene, en la cabecera, un campo identificado por una letra y un color por cada cambio que lleven al conflicto, en el ejemplo, un cambio concurrente en un método.

Semantic Merge tool

La magia

Para poder mostrar estos conflictos y resolver de manera automática aquellos en los que sea posible, analizamos los ficheros que el usuario nos pasa por parámetros, o a través de la pantalla inicial, si iniciamos sin parámetros (origen, destino y base).

Una vez hemos leído los ficheros y comprobado que no haya errores de análisis, creamos, para cada uno, un árbol semántico, similar a la ventana de clases que se puede ver en Visual Studio.

Semantic tree

Ya con estos árboles, comparamos el origen y el destino con la base para obtener lo que denominamos un árbol de diferencias. Finalmente comparamos estos árboles de diferencias para obtener los posibles conflictos y las diferentes formas de solucionarlos.

Escenarios

Hemos empleado cientos de horas de análisis, y procesado millones de repositorios para obtener las operacions y los conflictos más comunes, entre los que destacan:

  • Movidos divergentes: Si estamos haciendo refactor de nuestro código y movemos a diferentes partes del mismo (desarrollador A los prefiere por orden alfabético y desarrollador B los prefiere por orden de scope) detectamos el cambio y damos al usuario la opción de elegir.
  • Movidos/borrados: En caso de que un elemento (método, clase…) se haya movido en origen y se haya borrado en destino, lo detectamos y damos al usuario la opción de conservar el movido o el borrado.
  • Movidos + cambiados: En el caso de que un desarrollador mueva un método a otra clase y otro realice cambios en el mismo, se detectará automáticamente, y no habrá conflicto :)

Hay mucho más, disponible en semanticmerge.com

Integración

De momento, tenemos tutoriales sobre cómo integrarlo en Git, PlasticSCM, TFS y Perforce, y pronto deberíamos tener para Mercurial y SVN. Si usas otro sistema de control de versiones, avísanos!

Personalización

Mediante los parámetros de entrada, podemos especificar una herramienta de diff y merge personalizada, a través de los parámetros -emt y -edt de entrada. Además se puede especificar el tipo de fichero que estamos procesando aunque no tenga la extensión adecuada mediante el parámetro -t. En estos momentos el único lenguaje de programación soportado es C#, así que en este caso el único valor válido será text/csharp.

One more thing: Diferencias semánticas

Otra de las cosas que incorporamos es una herramienta de diff, que dados dos ficheros nos permite obtener las diferencias entre ellos.

difftool-included

Cómo se hizo

Aunque la idea ha estado en fase de análisis y diseño varios años, el desarrollo principal del proyecto se ha llevado a cabo en los úitimos 6 meses, en el que una buena parte del equipo de Códice ha estado implicada. Hemos estado divididos en dos grupos, uno encargado de las operaciones de merge y del backend de la herramienta, y otro grupo, que hemos estado cubriendo el diseño y la usabilidad de la herramienta.

Además, llevamos varias semanas usando la herramienta como herramienta de merge por defecto de manera interna, y las primeras betas privadas que distribuimos han tenido una acogida muy buena por parte de los voluntarios.

Bajo el capó

El lenguaje usado para todo el desarrollo de la app es C#, de ahí nuestro interés con que sea el primer lenguaje de programación soportado (llevamos semanas probando la herramienta a nivel interno).

La interfaz está desarrollada en WPF con algunos toques de Windows Forms, y para la ventana sin marco usamos la integración con Windows a través de Windows.Shell.

Las herramientas utilizadas han sido PlasticSCM como control de versiones, Visual Studio 2010 – 2012 como entorno de desarrollo y Blend 4 como herramienta de diseño de interfaces,

Pasos adicionales

Estamos en fase beta, con lo cual hay muchas cosas que pulir, además seguimos trabajando en mejorar la herramienta, la usabilidad, el diseño, la velocidad, así como el soporte para lenguajes adicionales y escenarios más complejos. Para ello hemos habilitado un portal en uservoice para recibir feedback de nuestros usuarios.

Desarrollando para Windows Phone 8, muchos errores y algún acierto

Este fin de semana he tenido la ocasión de desarrollar una pequeña aplicación de tareas para Windows Phone 8 para el concurso de desarrollo IAppYou. Como todo desarrollo, no ha estado libre de errores, así como de algún acierto que me gustaría repetir en el futuro, así que más que hablar de características o de cómo pasar información entre dos páginas, me pareció interesante compartir los aciertos, pero sobre todo, los errores.

Continuar leyendo «Desarrollando para Windows Phone 8, muchos errores y algún acierto»

Cómo configurar una máquina virtual de SQL Server 2012 en Azure

Con la última actualización de Azure, a la manera clásica de trabajar con SQL en la nube se le agrega una segunda opción, más potente, ya que nos permite contar con una máquina virtual completa con Windows Server a la cual podemos acceder remotamente, ajustar los servicios a nuestras necesidades, o instalar el software necesario para nuestra infraestructura.

Esta opción requiere algo de configuración, y este artículo pretende ser un pequeño resumen de temas a tener en cuenta a la hora de realizar la puesta a punto de este servicio:

  • Se puede crear la máquina virtual o bien desde línea de comandos o desde el portal de Azure. Para ello es necesario habilitar la característica, que en estos momentos se encuentra en fase Preview. Se ha de especificar que se trata de SQL Server 2012 Evaluation Edition, aunque se cuenta también con la edición 2008 R2.
  • El proceso de aprovisionamiento (copiar, instalar e iniciar la máquina por primera vez) tarda un rato, ya que tiene que crear los discos, copiar la información, y realizar una primera configuración.
  • Al realizar el aprovisionamiento, se configura automáticamente un endpoint para la conexión por RDP, pero es necesario habilitar otro para el puerto 1433 si queremos tener acceso remoto a la base de datos, esto se hace desde la vista de endpoints dentro del panel de la máquina virtual.
  • La máquina tiene el firewall activado por defecto, así que es necesario crear una regla para que permita el paso al puerto 1433 definido antes, la regla debe estar bajo Inbound Rules ya que se desea permitir conexiones entrantes.
  • Desde SQL Server Configuration Manager, habilitar las opciones Named PipesTCP/IP para poder acceder remotamente.
  • A no ser que se configure la máquina virtual para que forme parte de un dominio, será necesario activar la autenticación mixta (Windows y SQL Server) y crear un nuevo usuario para acceder remotamente, estableciendo los permisos adecuados. Ambas operaciones se realizan desde SQL Server Management Studio.
  • Si todo ha ido bien, se podrá realizar la conexión a la recién creada instancia desde un Management Studio local (disponible en el Centro de descargas de Microsoft)

La explicación completa, más ampliada, se puede encontrar en el Blog del equipo de Windows Azure

Sinatra, un framework web para Ruby

sinatra logo

Ruby es un lenguaje de programación que se ha hecho tremendamente conocido (de hecho es el lenguaje más usado en los repositorios de GitHub en estos momentos), Es un lenguaje dinámico y orientado a objetos que es sencillo de aprender. Además, posee diversos frameworks que lo convierte en un lenguaje potente para desarrollar aplicaciones web.

Uno de estos frameworks toma el nombre del célebre artista Frank Sinatra. Se usa en la actualidad por empresas como la BBC o la propia GitHub. Es tremendamente potente y bastante más sencillo que Ruby On Rails, más conocido y complejo. En este artículo veremos una brevísima introducción a qué es trabajar con Sinatra.

Instalación

Lo primero que necesitamos es una instalación de Ruby, para lo cual tenemos varios enlaces en su página oficial dependiendo de nuestro sistema operativo. Una vez instalado ruby podremos agregar nuevos paquetes usando RubyGems, y deberemos ejecutar el siguiente comando desde nuestra consola:

$ gem install sinatra

Descifrando el Hola Mundo

El hola mundo que nos ofrece el framework es muy sencillo, y es lo que podemos encontrar en la página principal. Acudimos a una carpeta cualquiera de nuestro sistema, y creamos un fichero llamado hi.rb:

require 'sinatra'

get '/hi' do
  "Hello World!"
end

Para ejecutar esta aplicación solamente tendremos que escribir el siguiente comando en nuestra terminal:


$ ruby -rubygems hi.rb
== Sinatra has taken the stage ...
>> Listening on 0.0.0.0:4567

A continuación se cargará el servidor de desarrollo de ruby, y solamente tendremos que acudir a localhost:4567 y ver nuestra página en funcionamiento.

El primer valor que se muestra es el comando HTTP al que responde (si recordamos este artículo los diferentes comandos HTTP son get, post, put, delete… ) con lo cual podemos hacer que nuestra aplicación responda a una petición en concreto, lo cual nos puede ser de gran utilidad si estamos desarrollando cualquier tipo de servicio web.

Además de mostrar código, podemos hacer uso de los diferentes motores de visualización que soporta. Uno de ellos se conoce como erb (acrónimo de embebed ruby), y permite tener en una página HTML código ruby.

Para ello editamos nuestra aplicación y agregamos el siguiente código:

...

get '/hello/:id' do
  @name = params[:id]
  erb :hello
end

Además necesitamos crear una carpeta llamada views (que contendrá las vistas de nuestra aplicación) y agregar el fichero, que tendrá extensión erb.



</pre>
<h2>Hello</h2>
<pre>


Esto no es del todo cómodo ya que nos obliga a repetir el código de marcado para cada vista que queramos tener en nuestra aplicación, sin embargo lo que podemos hacer es tener una plantilla que inserte cierto código antes y después de la vista, para lo cual usamos un fichero llamado layout.erb que contendrá la estructura básica del sitio, y actualizaremos el código para mostrar esta diferencia.


    
    

 


El código anterior contiene una etiqueta, yield, que especifica donde se ha de cargar el código específico de nuestra vista. El fichero de la vista actualizado contendría la siguiente información:

</pre>
<h2>Hello</h2>
<pre>

Con esto seríamos capaces de crear un portal básico que responda a ciertos parámetros de entrada.

Pasos adicionales

Tenemos mucho más que poder agregar a nuestra app: Modelos de datos con DataMapper, autorización con Warden, posibilidad de devolver los resultados en formato json (y usarlo entonces como un servicio web)… Las posibilidades son infinitas, pero todo comienza con get «/hi»….

Más información

Repositorios para versiones antiguas de Ubuntu

Una cosa que nos puede ocurrir es que estemos trabajando en una solución basada en Ubuntu y que, por las razones que sean, no sea posible/viable su actualización.

El problema radica en que los repositorios que se emplean para actualizar los paquetes van cambiando con el tiempo, con lo cual si seguimos usando una versión antigua llegará el día en que no pueda acceder al mismo.

La solución pasa por editar el fichero /etc/apt/sources.list, y sustituir la dirección que tengamos por la siguiente:

http://old-releases.ubuntu.com/ubuntu/

.En el momento de la redacción de este artículo se encontraban disponibles repositorios hasta la versión 4.10 de Ubuntu.

Imagen: CrystalXP 

Compilando C++ desde la consola de comandos de Visual Studio

Es posible que en alguna ocasión queramos compilar un fichero individual para comprobar el funcionamiento de una función o de un algoritmo, y abrir Visual Studio, cargar un proyecto y similar se nos antoje demasiado engorroso, una posible solución es usar la consola de comandos de visual studio, y compilar de una manera rápida. Para este artículo compilaré un fichero C++ nativo.

Para ello, si tenemos Visual Studio 2010 (Professional en mi caso), puedes  encontrar, dentro de la carpeta de Visual Studio 2010/Visual Studio Tools, una utilidad llamada Visual Studio Command Prompt (2010) que cargará el entorno de desarrollo.

Una vez ahí, usando los comandos clásicos (cd carpeta) o arrastrando la carpeta a la consola de comandos, nos situamos en el directorio donde queramos realizar la compilación y escribimos:

 \> cl /EHsc nombreDelFichero.cpp 

Donde cl es el compilador, y EH permite habilitar el manejo de excepciones. Esto debería realizar la compiilación correspondiente y generar un fichero llamado nombreDelFichero.exe

Si estás acostumbrado (por otros lenguajes u otros sistemas operativos) al uso intensivo de la consola de comandos, no has de renunciar a sus ventajas en la plataforma Windows/VS.

Más información (en inglés):

Configurando el APN de internet con Simyo en Windows Phone 7.5

Hace unos días tuve la suerte de conseguir un Nokia Lumia 800 desarrollando apps para Windows Phone, pero como mi tarifa actual de datos no era compatible y no quería comprometer la otra línea con una potabilidad o un cambio de contrato, decidí comprar una tarjeta con Simyo.

Al llegar la tarjeta e introducirla en el teléfono, no detectó los ajustes de conexión, con lo cual, tras un buen rato de búsqueda en la red, encontré la información que necesitaba.

Pasos para configurar Internet

  1. Introducir la SIM, encender el móvil, y activar la tarjeta (si has hecho alguna llamada y te han cogido el teléfono (es decir, se ha producido gasto), está activa).
  2. Navega hasta el menú de Configuración > Datos Móviles
  3. En él, has de asegurarte que están activadas las siguientes opciones:
    • Conexión de datos: Activada
    • Opciones de roaming de datos: Activar roaming
    • Conexión 3G: Activada
    • Selección de red: automático
  4. Pulsa en agregar apn (o editar apn si ya lo has intentado anteriormente), e introduce el siguiente dato:
    • APN: gprs-service.com

Es importante destacar que hemos activado la opción de activar roaming, con lo cual debemos recordar DESACTIVARLA cuando viajemos al extranjero ya que podemos incurrir en costes adicionales (y no precisamente pocos).

Actualización:

Al finalizar los pasos verás el icono de un triángulo en el área de notificación. Este icono indica que estás en Roaming (algo normal, ya que lo hemos habilitado en el paso 3).

Esto no indica que el operador te vaya a cobrar como si estuvieras en dicha zona, y lo puedes comprobar en tu zona de cliente de Simyo. Puedes ver el significado de los iconos del área de notificación aquí: ¿Qué significan los iconos del teléfono?