iphone ios localization internationalization localizable.strings

Localización de mensajes Plural Plural Sustantivo(por ejemplo, "5 elementos procesados") en iPhone utilizando Objective-C



ios localization (4)

Consideraría formas alternativas de mostrar la misma información, tal vez algo así como:

@"Items processed: %d"

MDC tiene una larga lista completa de reglas de pluralización si le interesa, pero realmente no creo que valga la pena el esfuerzo de implementar todas estas reglas. Otra cosa que deberías tener en cuenta es si algún idioma tendría el número después de la pluralización, ya que tiraría la cadena de formateo (no puedo pensar en ningún idioma que me salga de la cabeza, pero tal vez un lugar por precaución en cualquiera de sus cadenas localizadas más complicadas con números involucrados).

En mi aplicación actual, tengo un código que muestra un mensaje, por ejemplo, "5 elementos procesados". Para mantener la frase gramaticalmente correcta, es decir, si debe o no ser "5 elementos" o "5 elementos", utilizo el siguiente código:

int numItems = 5; NSString *myString = [[NSString alloc] initWithFormat:@"%d Item%@ Processed", numItems, (numItems == 1 ? @"" : @"s")];

Esto funciona bien por ahora. Pero estoy localizando mi aplicación, y quiero asegurarme de que el texto sea gramaticalmente correcto en todos los idiomas en los que estoy traduciendo la aplicación. Podría hacer algo como esto:

int numItems = 5; NSString *myString = (numItems == 1 ? NSLocalizedStringWithTable(@"%d Item Processed", @"myApp", @"singular version") : NSLocalizedStringWithTable(@"%d Items Processed", @"myApp", @"plural version"));

Sin embargo, no todos los idiomas tienen las mismas reglas sobre cómo funcionan los plurales. Por ejemplo, (perdone mi ejemplo muy específico aquí) en ruso, los sustantivos modificados con números que terminan en el último dígito 1 (es decir, 21, 31, pero no 11) toman el caso nominativo, los números que terminan en 2-4 toman el genitivo singular , y 5+ toman el caso genitivo plural. Esto requeriría una lógica mucho más seria para manejar cómo pluralizar un sustantivo particular de una manera gramaticalmente correcta, y esta lógica no coincidiría con la lógica inglesa. Por lo tanto, en teoría, no puedo tener la lógica gramatical en mi código Objective-C, sino que debería tener la lógica gramatical en el archivo de cadenas. ¿Hay alguna forma de hacer esto? ¿Cómo las personas traducen texto dinámico para sus aplicaciones para que siga siendo gramaticalmente correcto?


Mi equipo desarrolló una biblioteca de código abierto para manejar solo esta situación, revisa nuestra biblioteca i18n plural de iOS en github.

La premisa básica es que las claves para cadenas plurales se extienden para contener su forma plural de acuerdo con las reglas de plural de CLDR y la búsqueda de las cadenas no usa la cadena NSLocalizedString típica.

El archivo en inglés para el ejemplo publicado se vería así:

"%d Items Processed##{one}" = "1 Item Processed"; "%d Items Processed##{other}" = "%d Items Processed";

La búsqueda se haría usando una función SLPluralizedString

SLPluralizedString(@”%d Items Processed”, numItems, @”Number of items processed”);

En tiempo de ejecución, para el inglés, se devolverá la cadena "1 elemento procesado" o "% d elementos procesados" según el valor de los números.

El archivo ruso se vería así:

"%d Items Processed##{one}" = "%d элемент обработан"; "%d Items Processed##{few}" = "%d элемента обработано"; "%d Items Processed##{many}" = "%d элементов обработано"; "%d Items Processed##{other}" = "%d элемента обработано";

Su código y luego la búsqueda "Artículos procesados" para ruso o cualquier otro idioma no tendría que cambiar y la biblioteca devolvería la cadena correcta de acuerdo con las reglas de plural de CLDR para ese idioma en particular.

Por favor, siéntete libre de compartir tus pensamientos sobre la biblioteca, sugerencias, mejoras, etc.


En inglés, solo hay 2 formas en plural, por ejemplo, "1 archivo" y "5 archivos". En ruso, hay 3 formas de plural (101 файл, 2 файла, 11 файлов), a menos que cuentes no enteros. De hecho, en realidad puede haber hasta 6 formas plurales en un idioma (por ejemplo, el árabe tiene 6). Parece haber 3 formas de lidiar con el problema, simplemente elija lo que sea lo suficientemente bueno pero no demasiado complicado para usted:

  1. Intente utilizar mensajes neutros en plural, por ejemplo, "Número de elementos procesados:% d" en lugar de "% d elementos procesados ​​|% d elementos procesados".

  2. Admite localizaciones para cada forma plural, hasta 6.

    "%d Gold Coins##{PluralForm0}" -> "%d золотая монета" // e.g. 1 gold coin "%d Gold Coins##{PluralForm1}" -> "%d золотые монеты" // e.g. 2 gold coins "%d Gold Coins##{PluralForm2}" -> "%d золотых монет" // e.g. 5 gold coins … "%d Gold Coins##{PluralForm5}" -> "%d How did we get here if this is not Arabic???"

    Conociendo el valor de% d y el idioma de destino, tu aplicación tendrá que detectar el número de formulario plural en el tiempo de ejecución, es decir, implementar algo así como

    unsigned int "NumberToPluralFormNumber(unsigned int number, const std::string& langCode);

    método. Si solo admite entre 2 y 5 idiomas y los números en los mensajes siempre son entradas no negativas, en realidad es bastante sencillo implementarlo sin ninguna lib de 3 partes, puede copiar / pegar frases únicas compatibles con C para cada una. idioma de http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html . Tenga en cuenta que solo es válido para enteros no negativos, por lo que la cantidad de plurales puede diferir de lo que dice unicode.org.

  3. Libs de fiesta en 3D.

A partir de iOS 7, el marco de Foundation tiene soporte nativo para la pluralización. Aquí hay un tutorial rápido sobre cómo usarlo:

Cree un archivo plist nombrado como Localizable.stringsdict

Localización en inglés:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>%d tasks waiting for action</key> <dict> <key>NSStringLocalizedFormatKey</key> <string>%#@tasks@ waiting for action</string> <key>tasks</key> <dict> <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string> <key>NSStringFormatValueTypeKey</key> <string>d</string> <key>one</key> <string>A task is</string> <key>two</key> <string>Two tasks are</string> <key>other</key> <string>%d tasks are</string> </dict> </dict> </dict> </plist>

Localización polaca:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>%d tasks waiting for action</key> <dict> <key>NSStringLocalizedFormatKey</key> <string>Masz %#@zadanie@ do zrobienia</string> <key>zadanie</key> <dict> <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string> <key>NSStringFormatValueTypeKey</key> <string>d</string> <key>one</key> <string>jedno zadanie</string> <key>few</key> <string>%d zadania</string> <key>other</key> <string>%d zadań</string> </dict> </dict> </dict> </plist>

Y finalmente en su archivo de implementación, puede llamar al diccionario de esta manera:

cell.tasksInfoLabel.text = [NSString localizedStringWithFormat:NSLocalizedString(@"%d tasks waiting for action", @"%d tasks waiting for action"), (long)taskCount];

EDITAR: Gracias Zaphod por señalar esto ->: También necesitas crear el archivo Localizable.strings junto con el .stringsdict para que funcione la pluralización (incluso si está vacía).