Categorías del Tutorial

icono_twiter
Alejandro Pérez García

Alejandro es socio fundador de Autentia y nuestro experto en J2EE, Linux y optimización de aplicaciones empresariales.

Ingeniero en Informática y Certified ScrumMaster

Si te gusta lo que ves, puedes contratarle para darte ayuda con soporte experto, impartir cursos presenciales en tu empresa o para que realicemos tus proyectos como factoría (Madrid).
Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación.

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2012-04-18

Tutorial visitado 8.371 veces Descargar en PDF
Como hacer TDD con PHP gracias a PHPUnit

Como internacionalizar nuestras aplicaciones iOS 5 (iPhone, iPad, ...)

Creación: 16-04-2012



Índice de contenidos

1. Introducción
2. Entorno
3. Empecemos despacio, creemos una aplicación de ejemplo
4. Traduciendo los elementos del Storyboard
5. Traduciendo las cadenas dentro del código
6. Acceso a imágenes, ficheros, y otros recursos que dependen del idioma
7. Traducción del propio nombre de la aplicación
8. Conclusiones
9. Sobre el autor



1. Introducción

Cuando hacemos cualquier aplicación es muy importante la internacionalización (i18n) y la localización (L10n), sobre todo cuando estamos hablando de aplicaciones Web publicas en Internet que puede ser accedidas desde cualquier punto del mundo.

Con las aplicaciones móviles pasa lo mismo, ya que pueden ser descargadas desde los respectivos markets por cualquier usuario en cualquier parte del mundo. Por esto en este tutorial vamos a ver como podemos la internacionalización en aplicaciones iOS (iPhone, iPad, ...) o por lo menos la parte que se refiere a la traducción de recursos.

Y hablo de recursos en general porque nos vamos encontrar con elementos que están directamente en la interfaz de usuario (Views de nuestro Storyboard), también tendremos cadenas que vienen del modelo o que generamos programáticamente en runtime, imágenes y otros ficheros dependientes del idioma, ...

Al final del tutorial encontraréis un enlace con todo el código.



2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15' (2.5 GHz Intel i7, 8GB 1333 Mhz DDR3, 256GB Solid State Drive).

  • AMD Radeon HD 6770M 1024 MB

  • Sistema Operativo: Mac OS X Lion 10.7.3

  • Xcode 4.3.2

  • iOS 5.1



3. Empecemos despacio, creemos una aplicación de ejemplo

En este primer punto vamos simplemente a crear una aplicación para poder trabajar sobre ella. Abrimos nuestro Xcode y hacemos File --> New --> Project (Shift + Cmd + N)

Crear un proyecto en Xcode

Elegimos una aplicación con una única vista, con esto será más que suficiente.

Ahora damos el nombre de la aplicación y nos aseguramos de que tenemos marcados los checks: Use Storyboards, Use Automatic Reference Counting e Include Unit Test.

Indicar las características de un nuevo proyecto de Xcode

Luego indicaremos la ruta donde queremos crear el proyecto y finalmente se nos abrirá una ventana de Xcode con el proyecto recién creado.

Información general del nuevo proyecto de Xcode



4. Traduciendo los elementos del Storyboard

Sobre nuestra vista añadimos algunas etiquetas y les ponemos un texto directamente desde el Interface Builder. Estamos poniendo las etiquetas por defecto en inglés porque el Xcode cuando crea un proyecto nuevo asume que este es el idioma por defecto (esto se puede cambiar aunque no es tontería tomar el ingles como idioma por defecto ya que a nivel global seguramente hay más gente que entiende ingles que español).

Nótese que para ganar algo de espacio en el Interface Builder hemos pulsado sobre el icono de abajo a la izquierda para esconder el árbol de componentes.

Añadir una etiqueta al Storyboard

Ahora, teniendo marcado en el navegador de proyecto el ficheros MainStoryboard.storyboard, en las propiedades de Localization damos al botón + y añadimos Spanish.

Añadir un idoma para el Storyboard

Vemos como en el navegador de proyecto nos ha aparecido una copia del fichero MainStoryboard.storyboard. Esta estructura lógica se almacena en el disco duro en ficheros distintos en directorios distintos. De hecho encontraremos los directorios en.lproj y es.lproj donde almacenaremos todos los recursos traducidos para cada idioma (como hambréis adivinado los dos primeros caracteres de estos directorios están indicando el código de país).

Para traducir el Storyboard (también vale para ficheros nib o xib) vamos a usar una herramienta de línea de comandos llamada ibtool, que viene incluida en el Xcode. Primero vamos a ver si la tenemos correctamente instalada, porque por los cambios de versión de Xcode podemos tener algún problemilla.

Abrimos un Terminal y ejecutamos:

$ ibtool

Si vemos un mensaje del estilo:

Error: No developer directory found at /Developer. Run /usr/bin/xcode-select to update the developer directory path.

Es porque con la acutalización del Xcode ya no es necesario el directorio /Developer, y de hecho a ya no existe; así que le tenemos que decir a nuestro sistema donde se encuentra ahora el Xcode. Para ello ejecutamos:

$ sudo xcode-select -switch /Applications/Xcode.app

Ahora, si volvemos a ejecutar ibtool, no debería salir ningún mensaje si todo está correcto.

Ya tenemos el ibtool correctamente configurado, así que al lío. Nos vamos al directorio donde se encuentra nuestro MainStroyboard.storyboard para el idioma por defecto (recordar que en nuestro caso es el ingles, en el directorio en.lproj), y ejecutamos:

$ ibtool --export-strings-file /../../MainStoryboard_es.strings MainStoryboard.storyboard

Nótese que estamos generando el fichero MainStoryboard_es.strings en un directorio dos niveles por encima de donde nos encontramos, esto es, fuera del directorio de la aplicación; ya que este fichero no hace falta para empaquetar la aplicación (de hecho una vez terminado el proceso de traducción podríamos borrarlo).

Ahora abrimos este fichero con cualquier editor de texto y lo traducimos al español (por eso le pusimos el sufijo _es, aunque esto es sólo para que nosotros lo identifiquemos fácilmente). Veremos que es un fichero del estilo clave = valor. Ojo que sólo hay que traducir los valores. No tenemos que traducir ni las claves ni los comentarios!

Con el fichero traducido vamos a generar el MainStoryboard.storyboard en español. Para ello nos vamos al directorio es.lproj y ejecutamos:

$ ibtool --import-strings-file ../../MainStoryboard_es.strings --write MainStoryboard.storyboard ../en.lproj/MainStoryboard.storyboard

Esto nos genera un nuevo storyboard pero cambiando todas las cadenas por las traducidas.

Ojo, muy importante!!! Con el paso anterior hemos “machacado” el storyboard que teníamos!!! Por eso es muy importante que nunca toquemos el storyboard para un idioma concreto y siempre trabajemos sobre el fichero por defecto, porque al hacer la internacionalización perderemos los cambios!!!

Hay casos en los que parte de la internacionalización consiste en modificar particularmente la interfaz para un idioma concreto. Si no nos queda más remedio que hacer esto, ojo con el mantenimiento porque se puede complicar bastante ya que habrá que hacerlo a mano. En estos casos es posible que nos interese buscar una herramienta que nos ayude con al i18n (en el App Store podemos encontrar varias y a buen precio).

Si ahora volvemos al Xcode veremos que las cosas empiezan a salir en español :)

Etiquetas traducidas en el Storyboard


5. Traduciendo las cadenas dentro del código

Otro caso muy típico es cuando dentro de la aplicación generamos los mensajes. Vamos a ver como crear un botón al que le pongamos la etiqueta programáticamente. Para ello añadimos un botón a la interfaz y ahora pulsando Ctrl lo arrastramos hacia el fichero ViewController.h. Veremos como nos aparece una línea de conexión azul y como en el destino nos aparece un mensaje Insert Outlet, Action or Outlet Collection.

Crear Outlet de un botón en Xcode

Soltamos el ratón y nos aparece el detalle de la conexión (un Outlet es una referencia en nuestro código fuente a un elemento del Storyboard para que lo podamos modificar programáticamente).

Atributos de un Outlet al crearlo

Ponemos el nombre del botón y fijamos el Storage de tipo Strong (si no sabéis de que os hablo os recomiendo leer las guías de ARC, pero por ahora no decimos más ya que se sale mucho de este tutorial). El código nos quedará de este estilo:

Propiedad que se genera para referenciar el Outlet

Ahora editamos el ViewController.m y añadimos el código para poner la etiqueta del botón programáticamente.

Poner la etiqueta de un botón programáticamente

Pero, esta cadena no está internacionalizada?!?!?! Por supuesto que no, pero por algún sitio había que empezar. Ahora vamos a ver como hacer la internacionalización, simplemente modificamos el código para que quede la siguiente manera:

Etiqueta de botón internacionalizada en código

La función NSLocalizedString toma como primero parámetro una clave, y como segundo parámetro una descripción. Vemos que como clave hemos puesto el propio mensaje, esto es porque si el sistema no encuentra la clave, volcará esta en la interfaz, así que estamos usando las claves como los mensajes por defecto en ingles (por supuesto podemos usar el sistema de claves que más nos guste).

Ahora vamos a usar otra herramienta de línea de comando para generar el fichero que tendrá todas la cadenas que estemos usando en NSLocalizedString. Para ellos nos vamos al directorio en.lproj (aquí si es importante la localización del fichero) y ejecutamos:

$ genstrings ../*.m

Con esto se genera el fichero Localizable.strings con todas las cadenas que se usan en la función NSLocalizedString en todos los ficheros .m del directorio raíz de la aplicación (por eso lo de ../*.m). También podemos guardar las cadenas en otro fichero con otro nombre, pero por defecto el sistema buscará en Localizable.strings.

Ahora añadimos el fichero al Xcode. Para ello nos ponemos sobre el grupo Supporting Files y hacemos File --> Add Files to... (Alt + Cmd + A). Igual que hemos hecho antes nos vamos a la pestaña de Localization y añadimos con el botón + el idioma español.

Xcode - añadiendo un idioma para Localizable.strings

Igual que antes se nos ha creado una nueva versión de Localizable.strings que es una copia de la que tenemos, pero lo ha dejado en la carpeta es.lproj. Basta con pinchar sobre la versión española y traducirla. Igual que antes veremos que se trata de un fichero de tipo clave = valor. E igual que antes sólo tenemos que traducir, el valor. El comentario no merece la pena y por supuesto la clave hay que dejarla tal cual.

Si ahora ejecutamos la aplicación podemos ver como la etiqueta del botón sale en el idioma correcto seguna configuramos en el simulador el idioma del dispositivo.

Botón en inglés Botón en español



6. Acceso a imágenes, ficheros, y otros recursos que dependen del idioma

Ahora vamos a ver como podemos tener varios recursos que no son traducibles en runtime (como las imágenes) o que no nos interesa hacerlo por los sistemas que hemos visto anteriormente (por ejemplo un fichero de texto, que simplemente queremos cargar la versión adecuada y mostrarla). Aquí vamos a ver como podemos acceder al fichero correcto de forma transparente para nosotros.

En primer lugar vamos a colocar en la interfaz una vista para mostrar imágenes.

Añadir un UIImageView

También creamos un Outlet del UIImageView para poder manipularlo desde la aplicación.

Outlet de un UIImageView

Atributos de un Outlet para un UIImageView

Propiedad generada para el Outlet de un UIImageView

Ahora copiamos una imagen con un texto en ingles en la carpeta en.lproj, y como hicimos antes la añadimos al navegador de proyecto del Xcode en el grupo Supporting Files. Y como ya estamos acostumbrados, en la pestaña de Localization añadimos el idioma español. Esto hace que el Xcode copie la imagen en el directorio es.lproj

Añadir imagen a la carpeta de recursos

Ahora sustituimos la imagen del directorio es.lproj por una versión con texto en español.

Se añade la versión española de la imagen

Y ahora vamos a cargar la imagen adecuada programáticamente.

Cargar una imagen con NSBundle

Como veis es bastante sencillo, sólo hemos usado la clase NSBundle para localizar el recurso y luego lo hemos usado para cargar la imagen. Lo interesante aquí es que a la clase NSBundle no hay que decirle nada respecto al idioma. Esta clase primero busca el recurso en el directorio raíz, y si no lo encuentra lo busca en el directorio correspondiente al idioma que el usuario tiene definido en el dispositivo, y si no lo encuentra lo buscará en el idioma por defecto (recordar que en nuestro caso es el inglés - en).

Lo podéis comprobar en el simulador cambiando el idioma.



7. Traducción del propio nombre de la aplicación

Hay ciertos recursos que no los ponemos nosotros en la aplicación, sino que ya vienen “de serie” como por ejemplo el nombre de la aplicación. Esta es una propiedad que definimos durante la creación del proyecto y que también sería interesante que se pudiera traducir. Pues bien, sí es posible, y además muy sencillo!

Basta con buscar el fichero InfoPlist.strings en el grupo Supporting Files del navegador de proyecto del Xcode. Como hemos hecho siempre añadimos el idioma español, y ahora editamos la versión española del fichero para traducir la propiedad CFBundleDisplayName.

Traduciendo InfoPlist.strings

Nombre traducido de la aplicación

Esto mismo lo podríamos hacer en general con cualquier propiedad del fichero iOSTutorial-Info.plist, pero evidentemente sólo tiene sentido para aquellas propiedades que se acaban mostrando de alguna manera al usuario.



8. Conclusiones

Como hemos podido ver, hay multitud de recursos que necesitan traducción de una u otra manera, pero iOS lo resuelve de forma sencilla y unificada, de forma que el proceso al final siempre es prácticamente el mismo.

Con lo que hemos visto en este tutorial ya no se puede perdonar que no tengamos nuestra aplicación por lo menos en un par de idiomas, el nuestro nativo y yo apostaría por ingles o el chino si queremos llegar a un máximo de usuarios de nuestra aplicación :)

Os dejo todo el código del tutorial en este repositorio de GitHub.



9. Sobre el autor

Alejandro Pérez García, Ingeniero en Informática (especialidad de Ingeniería del Software) y Certified ScrumMaster

Socio fundador de Autentia (Desarrollo de software, Consultoría, Formación)

mailto:alejandropg@autentia.com

Autentia Real Business Solutions S.L. - "Soporte a Desarrollo"

http://www.autentia.com



A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL: