2009-10-27 15 views
9

En mi aplicación para el iPhone, tengo que mostrar el recuento de objetos que luego localizar, ya que Inglés hace la distinción de singular y plural, hago lo siguiente¿Cómo localizar números para la aplicación iPhone?

// pseudocódigo

 
if (objectList.count == 1) 
{ 
    NSLog(@"%@", NSLocalizedString(@"1 object", @"display one objects"); 
} 
else 
{ 
    NSLog(@"%@", NSLocalizedString(@"%d objects", @"display multiple objects"); 
} 

Esto funciona para Inglés pero en muchos otros idiomas, la forma plural de un sustantivo no se construye simplemente agregando una 's'.

As this page explains, hay dos cosas que pueden diferir entre las lenguas:

  • difiere la forma cómo las formas plurales están construidas. Este es un problema con idiomas que tienen muchas irregularidades . El alemán, por ejemplo, es un caso drástico. Aunque inglés y alemán son parte de la misma familia de idioma (germánico), la formación casi regular forma de sustantivo plural (añadiendo un 's') apenas se encuentra en alemán.
  • El número de formas plurales difiere. Esto es algo sorprendente para aquellos que solo tienen experiencia con Romanic y lenguajes germanos ya que aquí el número es el mismo (hay dos).

¿Cómo debo lidiar con esto en mi código?

+0

No es un problema específico ruso - hay otras lenguas para las que necesitará más de un plural. –

+3

Consulte http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html para obtener una explicación más detallada del problema (así como una lista bastante larga de idiomas con irregularidades). –

+0

Gracias Pavel, he editado la pregunta en consecuencia – zvolkov

Respuesta

11

NSLocalizedString va a leer desde una tabla de cadenas en su paquete de aplicaciones. Por lo tanto, la lista de idiomas que necesita para admitir se conoce en tiempo de compilación. En lugar de preocuparse por cómo codificar cada idioma posible, solo respalde los que está soportando.

Si su traductor viene a ti y dice que, para apoyar a Marte, se necesita una ortografía diferente para los números pares e impares, se puede ajustar el código a continuación, a algo como:

if (objectList.count == 1) { 
    NSLocalizedString(@"ObjectCount1", @"display one"); 
} else if (objectList.count % 2 == 0) { 
    NSLocalizedString(@"ObjectCountEven", @"display even"); 
} else if (objectList.count % 2 == 0) { 
    NSLocalizedString(@"ObjectCountOdd", @"display odd"); 
} 

en.lproj /Localizable.strings:

ObjectCount1 = "1 object"; 
ObjectCountEven = "%d objects"; 
ObjectCountOdd = "%d objects"; // same as ObjectCountEven 

mars.lproj/Localizable.strings:

ObjectCount1 = "1 object-o"; 
ObjectCountEven = "%d object-e"; 
ObjectCountOdd = "%d object-o"; // same as ObjectCount1 

Perdón si esto suena menos que ideal, pero los idiomas humanos son desordenados e irregulares, por lo que es una pérdida de tiempo tratar de encontrar una solución elegante, unificada y común para todos ellos. No hay uno.

4

Acabo de publicar JJPluralForm, una adaptación para Mozilla's PluralForm.

Con eso, no tendrías que preocuparte por hacer todo el código if-else, switch-case para localizar en tu código, que se vuelve imposible de mantener a medida que crece tu número de localizaciones.

Algo así como el ejemplo que diste podría ser manejado con:

[[JJPluralForm sharedManager] pluralStringForNumber:numberOfObjects 
            withPluralForms:NSLocalizedString(@"N_OBJECTS_PLURAL_STRING", @"") 
            localizeNumeral:YES]; 

Cada localizable.archivo de cadenas a continuación, localizar N_OBJECTS_PLURAL_STRING como una lista separada por punto y coma de formas plurales. Para inglés, eso sería "%@ object;%@ objects".

Consulte el proyecto para obtener más detalles.

+0

¡Qué bueno, manejas la doble caja árabe! – benzado

3

Smartling ha lanzado un marco de código abierto para admitir plurales siguiendo el estándar CLDR.

https://github.com/Smartling/ios-i18n

Para usarlo se agrega un marcador especial en las llaves que siguen etiquetado estilo CLDR y llamar SLPluralizedString en lugar de NSLocalizedString. . En tiempo de ejecución de la biblioteca recogerá la cadena de derecho de uso basado en el lenguaje de la aplicación se está ejecutando actualmente en

Así archivo de su Inglés .strings tendría:

"%@ apples##{one}" = "One apple"; 
"%@ apples##{other}" = "%@ apples"; 

El archivo .strings ruso:

"%@ apples##{one}" = "%@ яблоко"; 
"%@ apples##{few}" = "%@ яблока"; 
"%@ apples##{many}" = "%@ яблок"; 
"%@ apples##{other}" = "%@ яблока"; 

y el código para llamar a que podría parecerse a:

NSString *s2 = [NSString stringWithFormat:SLPluralizedString(@"%@ apples", number, nil), number]; 
No

Este ejemplo demuestra una de las mejores cosas de esta biblioteca: le permite escribir sus cadenas originales o traducciones con un lenguaje expresivo que incluso podría no usar el especificador de formato.

En este momento soy un Gerente de Producto con Smartling.

0

Existe una solución aún más poderosa para este problema. Echar un vistazo a la biblioteca de Tr8n TranslationExchange.com

https://github.com/tr8n/tr8n_objc_clientsdk

La biblioteca utiliza TML de TranslationExchange (Traducción Markup Language), lo que hace muy fácil el proceso de internacionalización. Antes que nada, ni siquiera es necesario tratar con los archivos Strings XML nunca más, realmente ... - Tr8n SDK creará y administrará sus archivos String sobre la marcha - nunca los volverá a ver.

Su ejemplo particular sería simplemente:

Tr8nLocalizedStringWithTokens(@"{count || object}", @{@"count": objectList.count}) 

biblioteca Tr8n automáticamente tomará la forma plural adecuado para usted en cualquier idioma. ¿Hah? Sí, es mágico. La forma completa de la señal ejemplo anterior es en realidad:

{count:number || one: object, other: objects} 

Eso significa que token "recuento" es de un tipo numérico que se asigna a los plurales en inglés utilizando palabras clave "uno" y "otros" .... Pero Tr8n es lo suficientemente inteligente como para no tener que escribir todo eso. También es lo suficientemente inteligente como para asignar la secuencia de parámetros a los valores de regla apropiados también. Y, por supuesto, sabe que el "conteo" está asociado con las reglas numéricas a través de la convención de nomenclatura.Por lo que simplemente se convierte en:

{count || object} 

Por cierto, ya que se ha mencionado ruso, la traducción al ruso de lo anterior sería simplemente:

"{count || object}" = "{count || объект, объекта, объектов}" 

este ejemplo era demasiado fácil, vamos a echar un vistazo a una más interesante:

Tr8nLocalizedStringWithTokens(
    @"{user} uploaded {count || photo} to {user | his, her} photo album.", 
    @{@"user": user, @"count": 5} 
) 

en primer lugar, la buena suerte traducir esta frase usando la biblioteca i18n iOS estándar (o cualquier otra biblioteca para el caso) ... es una broma - pero en realidad, no hay manera de hazlo usando cualquier cosa, pero Tr8n.

Lo anterior TML traducido a Rusia sería simplemente:

@"{user || загрузил, загрузила} {count || фотографию, фотографии, фотографий} в свой фотоальбом." 

Aquí nos ocupamos de género gobierna la misma forma en que tratamos con las reglas numéricas. Pero en lugar de "uno", "pocos", "otros", tenemos "masculino", "femenino", "desconocido"; bueno, cada idioma puede tener diferentes reglas numéricas y de género. Tr8n lo resolverá, por lo que no es necesario.

Bien, pasemos al siguiente nivel. Usted ha decidido que debe tener la cantidad de fotos en negrita. Pedazo de pastel.

Tr8nLocalizedAttributedStringWithTokens(
    @"{user} uploaded [bold: {count || photo}] to {user | his, her} photo album.", 
    @{ 
    @"user": user, 
    @"count": 5, 
    @"bold": @{@"font":@{@"name": @"system", @"size": @12, @"type": @"bold"}} 
    } 
) 

[bold: ...] es una ficha de decoración. ¿Notaste que cambiamos la macro a la versión AttributedString? Esta macro realmente produciría un NSAttributedString usando el mecanismo de decoración nativo de iOS. ¿Puedes adivinar cuál sería la traducción en ruso?

@"{user || загрузил, загрузила} [bold: {count || фотографию, фотографии, фотографий}] в свой фотоальбом." 

Por cierto, puede predefinir todas sus fichas decoración en otros lugares, por lo que no tiene que mantener su definición cada vez.

Vamos a hacer un ejemplo más definitivo ... Diga, usted tiene una historia de suministro de noticias en la forma siguiente:

Tr8nLocalizedAttributedStringWithTokens(
    @"{actor} sent {target} [bold: {count || gift}].", 
    @{ 
    @"actor": user1, 
    @"target": user2, 
    @"count": 5 
    } 
) 

No parece interesante en Inglés. Pero lo hace en ruso o en cualquier otro idioma que admita casos de idioma. El nombre de {target}, si resulta ser en ruso, en realidad tendrá que usar Russian Dative Language Case.

http://en.wikipedia.org/wiki/Dative_case

Si usted no habla ruso, es probable que no necesita saber acerca de ella. Pero tus traductores rusos deberían. Vamos a ver a continuación, la traducción al ruso:

@"{actor || подарил, подарила} {target::dat} [bold: {count || подарок, подарка, подарков}].", 

Tr8n es lo suficientemente inteligente como para usar su potente motor de reglas del lenguaje y aplicar el lenguaje caso dativo a los nombres rusos pasaron por el símbolo {target} ...

Eso fue una respuesta larga para una simple pregunta numérica. Gracias por leerlo tan lejos. Espero eso ayude.

Descargo de responsabilidad: Soy el creador de framework Tr8n y lenguaje TML. Si tiene alguna pregunta, haga "ping me" y me encantaría ayudarlo con todas sus preguntas de traducción.

2

Por cierto, a partir de iOS 7 y Mac OS X 10.9, hay soporte incorporado para plurales en la localización.Consulte el WWDC 2013 video "Cómo hacer que su aplicación esté lista para el mundo" a partir de las 16:10. Plurales se localizan en un archivo plist .stringsdict, y entonces sólo hacen

NSLog(@"%@", [NSString localizedStringWithFormat: 
      NSLocalizedString(@"%d objects", @"display multiple objects"), n]); 
Cuestiones relacionadas