NSLocalizedString con variable rápida

85

Estoy intentando localizar mi aplicación usando NSLocalizedString. Cuando importo el archivo XLIFF, la mayoría funciona como un encanto, pero algo no y algunas cadenas no están localizadas. He notado que el problema es de NSLocalizedString que contiene algo variable dentro como:

NSLocalizedString(" - \(count) Notifica", comment: "sottotitolo prescrizione per le notifiche al singolare")

o

NSLocalizedString("Notifica per \(medicina!) della prescrizione \(prescription!)\nMemo: \(memoTextView.text)", comment: "Messaggio della Local Notification")

Quizás esta no sea la sintaxis correcta para este tipo de cosas. ¿Alguien me puede explicar cómo hacer eso en rápido? Muchas gracias.

Andorath
fuente
Este es un muy buen artículo sobre la localización en Swift para una arquitectura robusta
Mendy

Respuestas:

133

Puede usar los sprintfparámetros de formato dentro NSLocalizedString, por lo que su ejemplo puede verse así:

let myString = String(format: NSLocalizedString(" - %d Notifica", comment: "sottotitolo prescrizione per le notifiche al singolare"), count)
zisoft
fuente
6
¿Cómo se ve en Localizable.string?
Van Du Tran
Igual que en Obj-C:" - %d Notifica"=" - %d Notifica";
ReDetection
3
¿Cómo sustituyo una cuerda? Traté de usar el %smodificador que no funcionó = \
igrek
12
@igrek Se utiliza %@para sustituir una cadena.
Yeehaw
2
La referencia para estos parámetros de formato es developer.apple.com/library/content/documentation/Cocoa/…
Shaun Dychko
94

En la Sesión # 412 de WWDC2014 "Localización con Xcode 6", la forma correcta de hacerlo en Swift es la siguiente:

String.localizedStringWithFormat(
    NSLocalizedString(" - %d Notifica",
    comment: "sottotitolo prescrizione per le notifiche al singolare"),
    count)
marca
fuente
¿Por qué necesita utilizar NSLocalizedString (...)? ¿no sucede en la implementación de String.localizedStringWithFormat (...)?
Itzjak
2
Echa un vistazo ( stackoverflow.com/questions/26237549/… )
Mark
1
Gracias, ya lo vi después de que pregunté. Será muy útil para los demás, así que gracias
Itzjak
25

He seguido el enfoque de crear una extensión para String ya que tengo muchas cadenas para localizar.

extension String {
    var localized: String {
        return NSLocalizedString(self, comment:"")
    }
}

Para usarlo para la localización en código, haga lo siguiente:

self.descriptionView.text = "Description".localized

Para cadenas con variables dinámicas, siga:

self.entryTimeLabel.text = "\("Doors-open-at".localized) \(event.eventStartTime)"

Declare las cadenas en archivos de cadena para diferentes idiomas (ejemplo: árabe e inglés)

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

¡Hope te ayudará!

JaspreetKour
fuente
2
Pero me parece que solo estás agregando el tiempo a la cuerda. ¿Qué pasa si su cadena localizada fuera como The doors open at %@ o'clock. ¿Seguiría funcionando tu solución?
Houman
Sí, está funcionando perfectamente ya que estoy recibiendo tiempo como String desde atrás.
JaspreetKour
1
Gracias por incluir una referencia a Localizable.strings. Sin embargo, creo que @Houman tiene una preocupación válida.
Matt
No sé por qué la gente quiere abandonar el valor de "comentario". Proporciona la descripción del texto y su propósito a los ingenieros de localización sin los cuales no pueden distinguir la intención de usar ese texto en un botón o como una etiqueta, etc.
Satyam
7

Probé las soluciones anteriores, sin embargo, el siguiente código funcionó para mí

SWIFT 4

extension String {

    /// Fetches a localized String
    ///
    /// - Returns: return value(String) for key
    public func localized() -> String {
        let path = Bundle.main.path(forResource: "en", ofType: "lproj")
        let bundle = Bundle(path: path!)
        return (bundle?.localizedString(forKey: self, value: nil, table: nil))!
    }


    /// Fetches a localised String Arguments
    ///
    /// - Parameter arguments: parameters to be added in a string
    /// - Returns: localized string
    public func localized(with arguments: [CVarArg]) -> String {
        return String(format: self.localized(), locale: nil, arguments: arguments)
    }

}

// variable in a class
 let tcAndPPMessage = "By_signing_up_or_logging_in,_you_agree_to_our"
                                     .localized(with: [tAndc, pp, signin])

// Localization File String
"By_signing_up_or_logging_in,_you_agree_to_our" = "By signing up or logging in, you agree to our \"%@\" and \"%@\" \nAlready have an Account? \"%@\"";
Pratik
fuente
6

Aquí hay una extensión que uso en String, agrega una función localizeWithFormat con argumentos variables,

extension String:{

     func localizeWithFormat(arguments: CVarArg...) -> String{
        return String(format: self.localized, arguments: arguments)        
     }

     var localized: String{
         return Bundle.main.localizedString(forKey: self, value: nil, table: "StandardLocalizations")
     }
}

Uso:

let siriCalendarText = "AnyCalendar"
let localizedText = "LTo use Siri with my app, please set %@ as the default list on your device reminders settings".localizeWithFormat(arguments: siriCalendarTitle)

Solo tenga cuidado de no usar los mismos nombres de función y propiedad que tiene String. Normalmente uso un prefijo de 3 letras para todas mis funciones de marco.

el reverendo
fuente
-5

Creé un extensionto Stringya que tenía muchos stringsque ser localized.

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

Por ejemplo:

let myValue = 10
let anotherValue = "another value"

let localizedStr = "This string is localized: \(myValue) \(anotherValue)".localized
print(localizedStr)
Santosh
fuente
6
La gran desventaja de este enfoque es que debe extraer manualmente las cadenas para enviarlas al traductor, ya Editor > Export for Localization...que no las recogerá.
Jason Moore
Dado lo que sugirió @JasonMoore, no creo que este sea el enfoque correcto.
Yuchen Zhong
@JasonMoore está totalmente de acuerdo contigo. ¿Alguno de ustedes encontró una solución para esto?
gasparuff
No sé por qué se rebaja esta solución :(. y casi la solución de abajo nido a continuación es la misma, pero ha aumentado
Amr Angry