2009-10-27 8 views
9

Nel mio iPhone app, ho bisogno di visualizzare i conteggi degli oggetti che ho poi localizzare, in quanto inglese fa la distinzione di singolare e plurale, faccio la seguenteCome localizzare i numeri per l'app per iPhone?

// pseudo

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

Questo funziona per l'inglese ma in molte altre lingue la forma plurale di un sostantivo non è semplicemente costruita aggiungendo una "s".

As this page explains, ci sono due cose che possono differire tra lingue

  • La forma DIFFERISCE come forme plurali sono costruite. Questo è un problema con le lingue che hanno molte irregolarità . Il tedesco, ad esempio, è un caso drastico. Anche se l'inglese e il tedesco appartengono alla stessa lingua (tedesco), la forma quasi regolare di forme nominali (in aggiunta a una "s") è difficilmente reperibile in tedesco.
  • Il numero di forme plurali differiscono. Questo è un po 'sorprendente per quelli che hanno solo esperienze con Romanic e lingue germaniche poiché qui il numero è lo stesso (ce ne sono due).

Come devo gestire questo nel mio codice?

+0

Non è un problema specifico-Russo - ci sono altre lingue per cui avrete bisogno di più di un plurale. –

+3

Vedere http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html per una spiegazione più dettagliata del problema (oltre a un elenco abbastanza lungo di lingue con irregolarità). –

+0

Grazie Pavel, ho modificato la domanda di conseguenza – zvolkov

risposta

11

NSLocalizedString sta per essere letto da una tabella di stringhe nel pacchetto di app. Pertanto, l'elenco delle lingue che è necessario supportare è noto al momento della compilazione. Piuttosto che preoccuparti di come codificare per ogni lingua possibile, basta supportare quelli che stai supportando.

Se il traduttore viene a voi e dice che, per sostenere marziana, è necessario un ortografico separato per i numeri pari e dispari, è possibile regolare il codice poi, a qualcosa di simile:

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 

Scusa se questo suona meno che ideale, ma i linguaggi umani sono disordinati e irregolari, quindi è una perdita di tempo cercare di trovare una soluzione comune elegante, unificata per tutti loro. Non ce n'è uno.

4

Ho appena pubblicato JJPluralForm, un adattamento per PluralForm di Mozilla.

Con questo, non dovresti preoccuparti di fare tutto il codice if-else, switch-case per localizzare il tuo codice, che diventa impossibile da mantenere man mano che il numero di localizzazioni aumenta.

Qualcosa di simile l'esempio che ha dato potrebbe essere gestita con:

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

Ogni Localizable.il file di stringhe quindi localizza N_OBJECTS_PLURAL_STRING come un elenco separato da punti e virgola di forme plurali. Per l'inglese, sarebbe "%@ object;%@ objects".

Dai un'occhiata al progetto per maggiori dettagli.

+0

Oh bello, tu gestisci il doppio caso arabo! – benzado

3

Smartling ha rilasciato un framework open source per supportare i plurali seguendo lo standard CLDR.

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

Per usarlo si aggiunge un marcatore speciale nelle vostre chiavi che seguono CLDR etichettatura stile e chiamare SLPluralizedString invece di NSLocalizedString. . In fase di esecuzione la biblioteca sceglierà la stringa diritto di utilizzare in base alla lingua l'applicazione è in esecuzione in

Così file di vostro inglese .strings avrebbe:

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

Il file .strings russo:

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

e il codice per chiamare potrebbe apparire come:

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

Questo esempio dimostra una delle grandi cose di questa libreria: consente di scrivere stringhe o traduzioni originali con un linguaggio espressivo che potrebbe non utilizzare nemmeno l'identificatore di formato.

Al momento della scrittura sono un Product Manager con Smartling.

0

C'è una soluzione ancora più potente a questo problema. Date un'occhiata alla biblioteca Tr8n da TranslationExchange.com

https://github.com/tr8n/tr8n_objc_clientsdk

La libreria utilizza del TranslationExchange TML (Traduzione Markup Language), il che rende il processo di internazionalizzazione molto semplice. Prima di tutto, non hai nemmeno più bisogno di gestire i file XML di Strings, davvero ... - l'SDK Tr8n creerà e gestirà i tuoi file String per te al volo - non li guarderai mai più.

Il vostro esempio particolare sarebbe semplicemente:

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

biblioteca Tr8n sceglierà automaticamente la forma plurale giusto per voi in qualsiasi lingua. Hah? Sì, è magico. La forma completa dell'esempio gettone sopra è in realtà:

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

Ciò significa che segnalino "conteggio" è di tipo numerico che viene mappato plurali inglese con parole chiave "uno" e "altro" .... Ma Tr8n è abbastanza intelligente da non averti scritto tutto questo. È anche abbastanza intelligente da mappare la sequenza di parametri ai valori delle regole appropriate. E, naturalmente, sa che "contare" è associato alle regole numeriche attraverso la convenzione di denominazione.Così diventa semplicemente:

{count || object} 

Btw, dal momento che hai citato russo, la traduzione russa per quanto sopra sarebbe semplicemente:

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

questo esempio era troppo facile, diamo uno sguardo ad un più interessante:

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

Prima di tutto, buona fortuna a tradurre questa frase utilizzando la libreria standard di iOS i18n (o qualsiasi altra libreria è per questo) ... è uno scherzo - ma in realtà, non c'è modo per fallo usando qualsiasi cosa, ma Tr8n.

È possibile che questo TML tradotto in russo sarebbe semplicemente:

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

Qui abbiamo a che fare con il sesso regole allo stesso modo abbiamo a che fare con le regole numeriche. Ma invece di "uno", "pochi", "altro", abbiamo "maschio", "femmina", "sconosciuto" - beh, ogni lingua può avere differenti regole di genere e numeriche. Tr8n ci penserà, quindi non devi.

OK, passiamo al livello successivo. Hai deciso che devi avere il numero di foto per essere in grassetto. Pezzo di torta.

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

[grassetto: ...] è un token di decorazione. Hai notato che abbiamo commutato la macro nella versione AttributedString? Questa macro produrrebbe effettivamente una NSAttributedString usando il meccanismo di decorazione nativo di iOS. Riuscite a indovinare quale sarebbe la traduzione in russo?

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

Btw, è possibile predefinire tutti i gettoni di decorazione altrove, quindi non c'è bisogno di tenere definire ogni volta.

Facciamo solo un altro esempio finale ... Di ', hai una storia newsfeed nella forma seguente:

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

Non sembra interessante in inglese. Ma lo fa in russo o in altre lingue che supportano casi linguistici. Il nome di {target}, se si trova in russo, avrà effettivamente bisogno di utilizzare il caso di lingua russa.

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

Se non parlate russo, probabilmente non c'è bisogno di sapere su di esso. Ma i tuoi traduttori russi dovrebbero. Vediamo la traduzione in russo poi:

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

Tr8n è abbastanza intelligente per utilizzare il suo potente motore di regole linguistiche e di applicare il caso dativo lingua per i nomi russi passati attraverso il {target} gettone ...

Quello era una risposta un po 'lunga per una semplice domanda numerica. Grazie per averlo letto così lontano. Spero che sia d'aiuto.

Disclaimer: Sono il creatore del framework Tr8n e del linguaggio TML. Se hai qualche domanda, per favore mandami un messaggio e mi piacerebbe aiutarti con tutte le tue domande di traduzione.

2

A proposito, a partire da iOS 7 e Mac OS X 10.9, esiste un supporto integrato per i plurali nella localizzazione.Vedi il WWDC 2013 video "Rendere la tua app pronta per il mondo" a partire dalle 16:10. Plurali sono localizzati in un file plist .stringsdict, e poi basta fare

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