Localizzazione in Xamarin.iOS

Questo documento illustra le funzionalità di localizzazione di iOS SDK e come accedervi con Xamarin.

Fare riferimento alle codifiche di internazionalizzazione per istruzioni sull'inclusione di set di caratteri/tabelle codici nelle applicazioni che devono elaborare dati non Unicode.

Funzionalità della piattaforma iOS

Questa sezione descrive alcune delle funzionalità di localizzazione in iOS. Passare alla sezione successiva per visualizzare codice ed esempi specifici.

Lingua

Gli utenti scelgono la lingua nell'app Impostazioni. Questa impostazione influisce sulle stringhe di lingua e sulle immagini visualizzate dal sistema operativo e nelle app.

Per determinare la lingua usata in un'app, ottenere il primo elemento di NSBundle.MainBundle.PreferredLocalizations:

var lang = NSBundle.MainBundle.PreferredLocalizations[0];

Questo valore sarà un codice linguistico, en ad esempio per l'inglese, es per lo spagnolo, ja per il giapponese e così via. Il valore restituito è limitato a una delle localizzazioni supportate dall'applicazione (usando regole di fallback per determinare la corrispondenza migliore).

Il codice dell'applicazione non deve sempre cercare questo valore: Xamarin e iOS forniscono entrambe funzionalità che consentono di fornire automaticamente la stringa o la risorsa corretta per la lingua dell'utente. Queste funzionalità sono descritte nella parte restante di questo documento.

Nota

Usare NSLocale.PreferredLanguages per determinare le preferenze linguistiche dell'utente, indipendentemente dalle localizzazioni supportate dall'app. I valori restituiti da questo metodo sono stati modificati in iOS 9; per informazioni dettagliate, vedere La nota tecnica TN2418 .

Impostazioni locali

Gli utenti scelgono le impostazioni locali nell'app Impostazioni. Questa impostazione influisce sulla modalità di formattazione di date, ore, numeri e valuta.

Ciò consente agli utenti di scegliere se visualizzano formati di ora di 12 ore o 24 ore, se il separatore decimale è una virgola o un punto e l'ordine di giorno, mese e anno nella visualizzazione data.

Con Xamarin è possibile accedere alle classi iOS di Apple (NSNumberFormatter) e alle classi .NET in System.Globalization. Gli sviluppatori devono valutare quale sia più adatto alle proprie esigenze, in quanto in ognuna sono disponibili funzionalità diverse. In particolare, se stai recuperando e visualizzando prezzi di acquisto in-app con StoreKit devi usare le classi di formattazione di Apple per le informazioni sul prezzo restituite.

Le impostazioni locali correnti possono essere sottoposte a query in uno dei due modi seguenti:

  • NSLocale.CurrentLocale.LocaleIdentifier
  • NSLocale.AutoUpdatingCurrentLocale.LocaleIdentifier

Il primo valore può essere memorizzato nella cache dal sistema operativo e quindi potrebbe non riflettere sempre le impostazioni locali attualmente selezionate dall'utente. Usare il secondo valore per ottenere le impostazioni locali attualmente selezionate.

Nota

Mono (il runtime .NET su cui si basa Xamarin.iOS) e le API iOS di Apple non supportano set identici di combinazioni di linguaggio/area geografica. Per questo motivo, è possibile selezionare una combinazione di lingua/area geografica nell'app iOS Impostazioni che non esegue il mapping a un valore valido in Mono. Ad esempio, l'impostazione di una lingua di i Telefono su Inglese e la relativa area geografica in Spagna causerà la generazione di valori diversi dalle API seguenti:

  • CurrentThead.CurrentCulture: en-US (API Mono)
  • CurrentThread.CurrentUICulture: en-US (API Mono)
  • NSLocale.CurrentLocale.LocaleIdentifier: en_ES (API Apple)

Poiché Mono usa CurrentThread.CurrentUICulture per selezionare le risorse e CurrentThread.CurrentCulture per formattare date e valute, la localizzazione basata su Mono (ad esempio, con file resx) potrebbe non produrre risultati previsti per queste combinazioni di lingua/area geografica. In queste situazioni, fare affidamento sulle API di Apple per localizzare in base alle esigenze.

NSCurrentLocaleDidChangeNotification

iOS genera un oggetto NSCurrentLocaleDidChangeNotification quando l'utente aggiorna le impostazioni locali. Le applicazioni possono restare in ascolto di questa notifica mentre sono in esecuzione e possono apportare modifiche appropriate all'interfaccia utente.

Nozioni di base sulla localizzazione in iOS

Le funzionalità seguenti di iOS vengono facilmente sfruttate in Xamarin per fornire risorse localizzate per la visualizzazione all'utente. Per informazioni su come implementare queste idee, vedere l'esempio TaskyL10n.

Specifica delle lingue predefinite e supportate in Info.plist

In Q&A QA1828 tecnico: Come iOS determina la lingua per l'app, Apple descrive come iOS seleziona una lingua da usare in un'app. I fattori seguenti influisce sulla lingua visualizzata:

  • Lingue preferite dell'utente (disponibili nell'app Impostazioni)
  • Localizzazioni in bundle con l'app (cartelle con estensione lproj)
  • CFBundleDevelopmentRegion (Valore Info.plist che specifica la lingua predefinita per l'app)
  • CFBundleLocalizations (Matrice Info.plist che specifica tutte le localizzazioni supportate)

Come indicato nel Q&A tecnico, CFBundleDevelopmentRegion rappresenta l'area e la lingua predefinita di un'app. Se l'app non supporta in modo esplicito le lingue preferite di un utente, userà la lingua specificata da questo campo.

Importante

iOS 11 applica questo meccanismo di selezione del linguaggio più rigorosamente rispetto alle versioni precedenti del sistema operativo. Per questo motivo, qualsiasi app iOS 11 che non dichiara in modo esplicito le localizzazioni supportate, incluse le cartelle con estensione lproj o impostando un valore per CFBundleLocalizations , può visualizzare una lingua diversa in iOS 11 rispetto a quella eseguita in iOS 10.

Se CFBundleDevelopmentRegion non è stato specificato nel file Info.plist, gli strumenti di compilazione Xamarin.iOS usano attualmente un valore predefinito .en_US Anche se questo potrebbe cambiare in una versione futura, significa che la lingua predefinita è inglese.

Per assicurarsi che l'app selezioni una lingua prevista, seguire questa procedura:

  • Specificare una lingua predefinita. Aprire Info.plist e usare la visualizzazione Origine per impostare un valore per la CFBundleDevelopmentRegion chiave. In XML dovrebbe essere simile al seguente:
<key>CFBundleDevelopmentRegion</key>
<string>es</string>

In questo esempio viene usato "es" per specificare che quando nessuna delle lingue preferite di un utente è supportata, per impostazione predefinita è spagnolo.

  • Dichiarare tutte le localizzazioni supportate. In Info.plist usare la visualizzazione Origine per impostare una matrice per la CFBundleLocalizations chiave. In XML dovrebbe essere simile al seguente:
<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>es</string>
    ...
</array>

Le app Xamarin.iOS localizzate con meccanismi .NET, ad esempio i file resx, devono fornire anche questi valori Info.plist .

Per altre informazioni su queste chiavi Info.plist, vedere Informazioni di riferimento sulla chiave dell'elenco delle proprietà di Apple.

Metodo GetLocalizedString

Il NSBundle.MainBundle.GetLocalizedString metodo cerca testo localizzato archiviato nei file con estensione strings nel progetto. Questi file sono organizzati in base alla lingua, in directory denominate appositamente con un suffisso lproj (si noti che la prima lettera dell'estensione è un "L").

Percorsi dei file con estensione strings

  • Base.lproj è la directory che contiene risorse per la lingua predefinita. Si trova spesso nella radice del progetto (ma può anche essere inserita nella cartella Risorse ).
  • <le directory language.lproj> vengono create per ogni lingua supportata, in genere nella cartella Risorse.

In ogni directory della lingua possono essere presenti diversi file con estensione strings :

  • Localizable.strings : l'elenco principale di testo localizzato.
  • InfoPlist.strings : alcune chiavi specifiche sono consentite in questo file per tradurre elementi come il nome dell'applicazione.
  • <storyboard-name.strings>: file facoltativo che contiene traduzioni per gli elementi dell'interfaccia utente in uno storyboard.

L'azione di compilazione per questi file deve essere Risorsa bundle.

Formato di file strings

La sintassi per i valori stringa localizzati è:

/* comment */
"key"="localized-value";

È consigliabile eseguire l'escape dei caratteri seguenti nelle stringhe:

  • Citazione di \"
  • \\ Barra rovesciata
  • \n Newline

Questo è un esempio di es/Localizable.strings (ad esempio. File spagnolo) dall'esempio:

"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";

Immagini

Per localizzare un'immagine in iOS:

  1. Fare riferimento all'immagine nel codice, ad esempio:

    UIImage.FromBundle("flag");
    
  2. Posizionare il file di immagine predefinito flag.png in Base.lproj (directory del linguaggio di sviluppo nativo).

  3. Facoltativamente, inserire le versioni localizzate dell'immagine nelle cartelle lproj per ogni lingua, ad esempio es.lproj, ja.lproj). Usare lo stesso nome file flag.png in ogni directory della lingua.

Se un'immagine non è presente per una determinata lingua, iOS eseguirà il fallback alla cartella predefinita della lingua nativa e caricherà l'immagine da questa posizione.

Avviare immagini

Usare le convenzioni di denominazione standard per le immagini di avvio (e i modelli XIB o Storyboard per i Telefono 6) quando vengono inserite nelle directory lproj per ogni lingua.

Default.png
Default@2x.png
Default-568h@2x.png
LaunchScreen.xib

Nome dell'app

L'inserimento di un file InfoPlist.strings in una directory lproj consente di eseguire l'override di alcuni valori dall'Info.plist dell'app, incluso il nome dell'applicazione:

"CFBundleDisplayName" = "LeónTodo";

Altre chiavi che è possibile usare per localizzare stringhe specifiche dell'applicazione sono:

  • CFBundleName
  • CFBundleShortVersionString
  • NSHumanReadableCopyright

Date e ore

Anche se è possibile usare le funzioni predefinite di data e ora di .NET (insieme all'oggetto corrente CultureInfo) per formattare date e ore per le impostazioni locali, ignora le impostazioni utente specifiche delle impostazioni locali (che possono essere impostate separatamente dalla lingua).

Usare iOS NSDateFormatter per produrre output che corrisponda alle preferenze delle impostazioni locali dell'utente. Il codice di esempio seguente illustra le opzioni di formattazione di base di data e ora:

var date = NSDate.Now;
var df = new NSDateFormatter ();
df.DateStyle = NSDateFormatterStyle.Full;
df.TimeStyle = NSDateFormatterStyle.Long;
Debug.WriteLine ("Full,Long: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Short;
df.TimeStyle = NSDateFormatterStyle.Short;
Debug.WriteLine ("Short,Short: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Medium;
df.TimeStyle = NSDateFormatterStyle.None;
Debug.WriteLine ("Medium,None: " + df.StringFor(date));

Risultati per l'inglese nel Stati Uniti:

Full,Long: Friday, August 7, 2015 at 10:29:32 AM PDT
Short,Short: 8/7/15, 10:29 AM
Medium,None: Aug 7, 2015

Risultati per lo spagnolo in Spagna:

Full,Long: viernes, 7 de agosto de 2015, 10:26:58 GMT-7
Short,Short: 7/8/15 10:26
Medium,None: 7/8/2015

Per altre informazioni, vedere la documentazione relativa ai formattatori data Apple. Durante il test della formattazione di data e ora sensibili alle impostazioni locali, controllare entrambe le impostazioni di lingua e area geografica i Telefono.

Layout da destra a sinistra (RTL)

iOS offre una serie di funzionalità per facilitare la creazione di app con riconoscimento RTL:

  • Usa gli attributi e trailing il leading layout automatico per l'allineamento dei controlli (che corrisponde a sinistra e a destra per l'inglese, ma viene invertito per le lingue RTL). Il UIStackView controllo è particolarmente utile per la disposizione dei controlli in grado di essere compatibile con RTL.
  • Usare TextAlignment = UITextAlignment.Natural per l'allineamento del testo (che verrà lasciato per la maggior parte delle lingue ma a destra per RTL).
  • UINavigationController capovolge automaticamente il pulsante Indietro e inverte la direzione dello scorrimento rapido.

Gli screenshot seguenti mostrano l'esempio di attività localizzato in arabo ed ebraico (anche se l'inglese è stato immesso nei campi):

Localization in Arabic

Localization in Hebrew

iOS inverte automaticamente l'oggetto UINavigationControllere gli altri controlli vengono posizionati all'interno UIStackView o allineati al layout automatico. Il testo RTL viene localizzato usando file con estensione strings nello stesso modo del testo LTR.

Localizzazione dell'interfaccia utente nel codice

L'esempio Tasky (localizzato nel codice) mostra come localizzare un'applicazione in cui l'interfaccia utente è incorporata nel codice (anziché INB o storyboard).

Struttura progetto

Screenshot shows the resources tree for a sample including the location of localizable strings.

File Localizable.strings

Come descritto in precedenza, il formato di file Localizable.strings è costituito da coppie chiave-valore. La chiave descrive la finalità della stringa e il valore è il testo tradotto da usare nell'app.

Le localizzazioni in spagnolo (es) per l'esempio sono illustrate di seguito:

"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";

Esecuzione della localizzazione

Nel codice dell'applicazione, ovunque sia impostato il testo visualizzato di un'interfaccia utente (sia il testo di un'etichetta o il segnaposto di un input e così via) il codice usa la funzione iOS GetLocalizedString per recuperare la traduzione corretta da visualizzare:

var localizedString = NSBundle.MainBundle.GetLocalizedString ("key", "optional");
someControl.Text = localizedString;

Localizzazione delle interfacce utente dello storyboard

L'esempio Tasky (storyboard localizzato) mostra come localizzare il testo nei controlli in uno storyboard.

Struttura progetto

La directory Base.lproj contiene lo storyboard e deve contenere anche eventuali immagini usate nell'applicazione.

Le altre directory del linguaggio contengono un file Localizable.strings per qualsiasi risorsa stringa a cui viene fatto riferimento nel codice, nonché un file MainStoryboard.strings che contiene traduzioni per il testo nello storyboard.

Screenshot shows the resources tree for a sample including the location of MainStoryboard strings.

Le directory del linguaggio devono contenere una copia di tutte le immagini localizzate, per eseguire l'override di quella presente in Base.lproj.

ID oggetto/ID localizzazione

Quando si creano e si modificano controlli in uno storyboard, selezionare ogni controllo e controllare l'ID da usare per la localizzazione:

  • In Visual Studio per Mac, si trova nel riquadro delle proprietà ed è denominato ID localizzazione.
  • In Xcode è denominato ID oggetto.

Questo valore stringa ha spesso una forma come "NF3-h8-xmR", come illustrato nello screenshot seguente:

Xcode view of Storyboard localization

Questo valore viene usato nel file stringhe per assegnare automaticamente il testo tradotto a ogni controllo.

MainStoryboard.strings

Il formato del file di traduzione dello storyboard è simile al file Localizable.strings , ad eccezione del fatto che la chiave (il valore a sinistra) non può essere definita dall'utente, ma deve avere un formato molto specifico: ObjectID.property.

Nell'esempio Mainstoryboard.strings riportato di seguito è possibile visualizzareUITextFielduna placeholder proprietà di testo che può essere localizzata; UILabels ha una text proprietà e UIButtonil testo predefinito è impostato usando normalTitle:

"SXg-TT-IwM.placeholder" = "nombre de la tarea";
"Pqa-aa-ury.placeholder"= "otra información de tarea";
"zwR-D9-hM1.text" = "Detalles de la tarea";
"bAM-2j-Rzw.text" = "Notas";           /* Notes */
"NF3-h8-xmR.text" = "Completo";        /* Done */
"MWt-Ya-pMf.normalTitle" = "Guardar";  /* Save */
"IGr-pR-05L.normalTitle" = "Eliminar"; /* Delete */

Importante

L'uso di uno storyboard con classi di dimensioni può comportare traduzioni che non vengono visualizzate nell'applicazione. Le note sulla versione Xcode di Apple indicano che uno storyboard o XIB non verranno localizzati correttamente se sono vere tre cose: usa classi di dimensioni, la localizzazione di base e la destinazione di compilazione sono impostate su Universale e le destinazioni di compilazione iOS 7.0. La correzione consiste nel duplicare il file di stringhe dello storyboard in due file identici: MainStoryboard~iphone.strings e MainStoryboard~ipad.strings, come illustrato nello screenshot seguente:

Strings files

Presentazione nell'App Store

Segui le domande frequenti di Apple sulla localizzazione dell'App Store per immettere traduzioni per ogni paese in cui la tua app è in vendita. Tieni presente che le traduzioni verranno visualizzate solo se l'app contiene anche una directory con estensione lproj localizzata per la lingua.

Riepilogo

Questo articolo illustra le nozioni di base sulla localizzazione delle applicazioni iOS usando le funzionalità predefinite di gestione delle risorse e storyboard.

Altre informazioni su i18n e L10n per app iOS, Android e multipiattaforma (inclusi Xamarin.Forms) sono disponibili in questa guida multipiattaforma.