it-swarm.com.de

Was ist NSLocalizedString in Swift?

Gibt es ein schnelles Äquivalent von NSLocalizedString(...)? In Objective-C verwenden wir normalerweise:

NSString *string = NSLocalizedString(@"key", @"comment");

Wie kann ich in Swift dasselbe erreichen? Ich habe eine Funktion gefunden:

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String

Es ist jedoch sehr lang und überhaupt nicht bequem.

206
RaffAl

Das NSLocalizedString existiert auch in der Welt von Swift.

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String

Die Parameter tableName, bundle und value sind mit einem Schlüsselwortdefaultmarkiert. Dies bedeutet, dass wir diese Parameter beim Aufruf der Funktion weglassen können. In diesem Fall werden ihre Standardwerte verwendet.

Dies führt zu der Schlussfolgerung, dass der Methodenaufruf vereinfacht werden kann:

NSLocalizedString("key", comment: "comment")
264
RaffAl

Ich benutze die nächste Lösung:

1) Erweiterung erstellen:

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

2) in Localizable.strings file:

"Hi" = "Привет";

3) Anwendungsbeispiel:

myLabel.text = "Hi".localized

genießen! ;)

--upd: -

Für den Fall mit Kommentaren können Sie diese Lösung verwenden:

1) Erweiterung:

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

2) in der .strings-Datei:

/* with !!! */
"Hi" = "Привет!!!";

3) mit:

myLabel.text = "Hi".localized(withComment: "with !!!")
352
dr OX

Eine Variation der vorhandenen Antworten:

Swift 4:

extension String {

    func localized(withComment comment: String? = nil) -> String {
        return NSLocalizedString(self, comment: comment ?? "")
    }

}

Sie können es dann einfach mit oder ohne Kommentar verwenden:

"Goodbye".localized()
"Hello".localized(withComment: "Simple greeting")

Beachten Sie jedoch, dass genstrings mit dieser Lösung nicht funktioniert.

14
José

Auf diese Weise können Sie eine unterschiedliche Implementierung für verschiedene Typen erstellen (z. B. Int oder benutzerdefinierte Klassen wie CurrencyUnit, ...). Es ist auch möglich, nach dieser Methode zu suchen, die mit dem Dienstprogramm genstrings .. aufgerufen wird

genstrings MyCoolApp/Views/SomeView.Swift -s localize -o .

erweiterung: 

import UIKit

extension String {
    public static func localize(key: String, comment: String) -> String {
        return NSLocalizedString(key, comment: comment)
    }
}

verwendungszweck:

String.localize("foo.bar", comment: "Foo Bar Comment :)")
11
Kay

Erstellt eine kleine Hilfsmethode für Fälle, in denen "Kommentar" immer ignoriert wird. Weniger Code ist leichter zu lesen:

public func NSLocalizedString(key: String) -> String {
    return NSLocalizedString(key, comment: "")
}

Setzen Sie es einfach an eine beliebige Stelle (außerhalb einer Klasse) und Xcode findet diese globale Methode.

7
JOM

Swift 3 Version:) ...

import Foundation

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

Der beste Weg ist wahrscheinlich dieser hier .

fileprivate func NSLocalizedString(_ key: String) -> String {
    return NSLocalizedString(key, comment: "")
}

und

import Foundation
extension String {
    static let Hello = NSLocalizedString("Hello")
    static let ThisApplicationIsCreated = NSLocalizedString("This application is created by the swifting.io team")
    static let OpsNoFeature = NSLocalizedString("Ops! It looks like this feature haven't been implemented yet :(!")
}

sie können es dann so verwenden

let message: String = .ThisApplicationIsCreated
print(message)

für mich ist das das Beste, weil

  • Die hartcodierten Zeichenfolgen befinden sich in einer bestimmten Datei. Der Tag, an dem Sie sie ändern möchten, ist wirklich einfach
  • Einfacher zu verwenden, als jedes Mal die Zeichenfolgen manuell in Ihre Datei einzugeben
  • genstrings funktionieren noch
  • sie können weitere Erweiterungen hinzufügen, z. B. eine pro Ansichtssteuerung, um die Dinge ordentlich zu halten
5
Robin Dorpe

Tatsächlich können Sie zwei Phasen verwenden, um Ihre Texte in Swift-Projekten zu übersetzen:

1) In der ersten Phase werden alle übersetzbaren Zeichenketten auf die alte Weise erstellt:

NSLocalisedString("Text to translate", comment: "Comment to comment")

1.1) Dann sollten Sie Genstrings verwenden, um Localizable.strings zu generieren:

$ genstrings *Swift

2) Anschließend sollten Sie diese Antwort verwenden.

2.1) Verwenden Sie die XCode-Option "Suchen und Ersetzen" auf der Grundlage des regulären Ausdrucks . Für das gegebene Beispiel (wenn Sie keine Kommentare haben) lautet der reguläre Ausdruck:

NSLocalizedString\((.*)\, comment:\ \"\"\) 

und ersetzen Sie es mit

$1.localized

oder (wenn Sie Kommentare haben)

NSLocalizedString\((.*)\, comment:\ (.*)\)

und ersetzen Sie es mit

$1.localizedWithComment(comment: $2)

Sie können beliebig mit Regex und verschiedenen Erweiterungskombinationen spielen. Der allgemeine Weg besteht darin, den gesamten Prozess in zwei Phasen zu teilen. Hoffentlich hilft das.

4
GYFK

Wenn Sie ein SDK entwickeln. Sie benötigen eine zusätzliche Operation.

1) Erstellen Sie Localizable.strings wie üblich in YourLocalizeDemoSDK.

2) Erstellen Sie dieselben Localizable.strings in YourLocalizeDemo.

3) Finden Sie Ihren Bundle-Pfad von YourLocalizeDemoSDK.

Swift4:

// if you use NSLocalizeString in NSObject, you can use it like this
let value = NSLocalizedString("key", tableName: nil, bundle: Bundle(for: type(of: self)), value: "", comment: "")

Bundle(for: type(of: self)) hilft Ihnen, das Bundle in YourLocalizeDemoSDK zu finden. Wenn Sie stattdessen Bundle.main verwenden, erhalten Sie einen falschen Wert (tatsächlich ist es dieselbe Zeichenfolge wie der Schlüssel).

Wenn Sie jedoch die durch dr OX erwähnte String-Erweiterung verwenden möchten. Sie müssen noch etwas tun. Die Origin-Erweiterung sieht folgendermaßen aus.

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

Wie wir wissen, entwickeln wir ein SDK. Bundle.main wird das Bundle von YourLocalizeDemos Bundle erhalten. Das wollen wir nicht. Wir benötigen das Bundle in YourLocalizeDemoSDK. Dies ist ein Trick, um es schnell zu finden.

Führen Sie den folgenden Code in einer NSObject-Instanz in YourLocalizeDemoSDK aus. Und Sie erhalten die URL von YourLocalizeDemoSDK.

let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL

Wenn Sie beide URLs drucken, werden Sie feststellen, dass wir die bundleURLofSDK-Basis auf mainBundleURL erstellen können. In diesem Fall wird es sein:

let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main

Und die String-Erweiterung lautet:

extension String {
    var localized: String {
        let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
        return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
    }
}

Ich hoffe es hilft.

2
Liam

Ich habe ein eigenes Genstrings-Tool entwickelt, mit dem Sie Strings mithilfe einer benutzerdefinierten Übersetzungsfunktion extrahieren können

extension String {

    func localizedWith(comment:String) -> String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: comment)
    }

}

https://Gist.github.com/Maxdw/e9e89af731ae6c6b8d85f5fa60ba848c

Es analysiert alle Ihre Swift-Dateien und exportiert die Strings und Kommentare in Ihrem Code in eine .strings-Datei.

Wahrscheinlich nicht der einfachste Weg, aber es ist möglich.

1
Max

Dies beantwortet zwar nicht das Verkürzungsproblem, aber es half mir beim Organisieren der Nachrichten. Ich habe jedoch eine Struktur für Fehlermeldungen wie unten beschrieben erstellt

struct Constants {
    // Error Messages
    struct ErrorMessages {
        static let unKnownError = NSLocalizedString("Unknown Error", comment: "Unknown Error Occured")
        static let downloadError = NSLocalizedString("Error in Download", comment: "Error in Download")
    }
}

let error = Constants.ErrorMessages.unKnownError

Auf diese Weise können Sie die Nachrichten organisieren und Genstrings zum Laufen bringen.

Und dies ist der Genstrings-Befehl

find ./ -name \*.Swift -print0 | xargs -0 genstrings -o .en.lproj
1
anoop4real

Hilfreiche Informationen für die Verwendung in Komponententests:

Dies ist eine einfache Version, die auf verschiedene Anwendungsfälle erweitert werden kann (z. B. bei Verwendung von tableNames).

public func NSLocalizedString(key: String, referenceClass: AnyClass, comment: String = "") -> String 
{
    let bundle = NSBundle(forClass: referenceClass)
    return NSLocalizedString(key, tableName:nil, bundle: bundle, comment: comment)
}

Verwenden Sie es so:

NSLocalizedString("YOUR-KEY", referenceClass: self)

Oder so mit einem Kommentar:

NSLocalizedString("YOUR-KEY", referenceClass: self, comment: "usage description")
1
GatoCurioso

Lokalisierung mit Standardsprache:

extension String {
func localized() -> String {
       let defaultLanguage = "en"
       let path = Bundle.main.path(forResource: defaultLanguage, ofType: "lproj")
       let bundle = Bundle(path: path!)

       return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
    }
}
0
researcher

Wenn Sie aus dem Englischen, wo ein Satz derselbe ist, in eine andere Sprache übersetzen, in der er anders ist (aufgrund des Geschlechts, der Verbkonjugation oder der Deklination) das einfachste NSString-Formular in Swift Das funktioniert in allen Fällen die drei Argumente eins. Der englische Ausdruck "vorher war" wurde beispielsweise für "weight" ("предыдущ ий был") und für "tail" ("предыдущ ая был_ anders ins Russische übersetzt.a ").

In diesem Fall benötigen Sie zwei unterschiedliche Übersetzungen für eine Quelle (in Bezug auf das in WWDC 2018 empfohlene XLIFF-Werkzeug). Sie können es nicht mit den zwei Argumenten NSLocalizedString erreichen, wobei "previous was" sowohl für die "key" als auch für die englische Übersetzung (d. H. Für den Wert) identisch ist. Die einzige Möglichkeit ist die Verwendung der drei Argumente

NSLocalizedString("previousWasFeminine", value: "previous was", comment: "previousWasFeminine")

NSLocalizedString("previousWasMasculine", value: "previous was", comment: "previousWasMasculine")

die Schlüssel ("previousWasFeminine" und "PreviousWasMasculine") unterscheiden sich.

Ich weiß, dass der allgemeine Rat darin besteht, die Phrase als Ganzes zu übersetzen, jedoch manchmal zu zeitaufwändig und unpraktisch.

0
Vadim Motorine