2017-02-25 4 views
1

Ich habe eine String-Erweiterung, die mir hilft, zu internationalisieren.Wie kann VarArgs zur Lokalisierung von Strings verwendet werden?

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

    func localized(args:CVarArg...) -> String{ 
     return NSString.localizedStringWithFormat(self.localized as NSString, args) as String 
    } 
} 

So kann ich leicht „hello_world“ .localized überall in der App verwenden kann, und es funktioniert gut.

Jetzt möchte ich die gleiche Funktionalität haben, aber auch in der Lage sein, Argumente zu übergeben. Das "CVarArg ..." zu überholen scheint jedoch nicht so zu funktionieren, wie ich es erwartet hätte.

"grant_gps_access".localized("MyApp")

Erwartetes Ergebnis: "Bitte gewähren MeineAnw GPS Zugang"

Tatsächliches Ergebnis: "Bitte gewähren (\ n MyApp \ n) GPS-Zugriff"

Was bin ich hier fehlt?

+0

http://StackOverflow.com/a/27914308/2303865 –

Antwort

4

Sie nicht eine variable Argumentliste an eine andere Funktion übergeben können, Sie eine CVaListPointer stattdessen passieren müssen (das Swift Äquivalent von va_list in C):

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

    func localized(args: CVarArg...) -> String { 
     return withVaList(args) { 
      NSString(format: self.localized, locale: Locale.current, arguments: $0) as String 
     } 
    } 
} 

Seit NSString.localizedStringWithFormat hat Einnahme keine Variante eine VAListPointer wird das Äquivalent NSString(format:, locale:, arguments:) mit dem aktuellen Gebietsschema verwendet.

Noch einfacher (Zuschreibung geht an @OOPer): Verwenden Sie String.init(format:locale:arguments:), die ein [CVarArg] Argument:

func localized(args: CVarArg...) -> String { 
     return String(format: self.localized, locale: Locale.current, arguments: args) 
    } 

Jetzt

"grant_gps_access".localized(args: "MyApp") 

sollte wie erwartet funktionieren, vorausgesetzt, dass die Zeichenketten-Datei enthält der Eintrag

"grant_gps_access" = "Please grant %@ GPS access"; 
+0

Sie können 'String.init (Format: locale: arguments:)' ohne Verwendung von 'withVaList' aufrufen. – OOPer

+0

@OOPer: Sie haben recht, das ist einfacher weil es ein '[CVarArg]' Argument braucht, das habe ich verpasst! –

Verwandte Themen