web-dev-qa-db-ja.com

Swiftと同等のNSLocalizedStringは何ですか?

NSLocalizedString(...)に相当するSwiftはありますか? Objective-Cでは、通常以下を使用します。

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

Swiftでどうすれば同じことができますか?私は関数を見つけました:

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

しかし、それは非常に長く、まったく便利ではありません。

211
RaffAl

NSLocalizedStringはSwiftの世界にも存在します。

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

tableNamebundle、およびvalueパラメータは、defaultキーワードでマークされています。つまり、関数の呼び出し中にこれらのパラメータを省略できるということです。この場合、それらのデフォルト値が使用されます。

これにより、メソッド呼び出しは次のように単純化できるという結論になります。

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

Swift 5 - 変更なし、まだそのように動作します。

267
RaffAl

私は次の解決策を使います:

1)拡張子を作成します。

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

2)Localizable.stringsファイルに:

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

3)使用例

myLabel.text = "Hi".localized

楽しい! ;)

- 更新: -

コメント付きの場合は、この解決策を使用できます。

1)拡張子:

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

2).stringsファイル内:

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

3)使用:

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

既存の答えのバリエーション:

Swift 4.2:

extension String {

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

}

あなたはそれから単にコメントの有無にかかわらずそれを使用できます:

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

ただし、genstringsはこのソリューションでは機能しません。

19
José

この方法を使用することで、異なる型(すなわちIntまたはCurrencyUnitなどのカスタムクラス)に対して異なる実装を作成することができます。 genstringsユーティリティを使って呼び出すこのメソッドをスキャンすることも可能です。コマンドにルーチンフラグを追加するだけです。

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

拡張:

import UIKit

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

使用法:

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

"comment"が常に無視される場合のための小さなヘルパーメソッドを作成しました。少ないコードで読みやすくなります。

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

それを(クラスの外側の)どこかに置くだけで、Xcodeはこのグローバルメソッドを見つけます。

7
JOM

スイフト3バージョン:)...

import Foundation

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

実際には、Swiftプロジェクトでテキストを翻訳するのに2つのフェーズを使用できます。

1)最初のフェーズでは、古い方法を使って翻訳可能なすべての文字列を作成します。

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

1.1)それから、Localizable.stringsを生成するためにgenstringsを使うべきです:

$ genstrings *Swift

2)その後、あなたはこの 答え を使うべきです。

2.1)正規表現に基づいてあなたのXCodeの "検索と置換"オプションを使う。与えられた例に関しては(あなたがコメントがなければ)、正規表現は次のようになります。

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

そしてそれを

$1.localized

または(コメントがある場合)

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

そしてそれを

$1.localizedWithComment(comment: $2)

あなたが望むようにあなたは自由に正規表現と異なる拡張子の組み合わせで遊ぶことができます。一般的な方法は、プロセス全体を2段階に分割することです。それが役立つことを願っています。

5
GYFK

おそらく一番良い方法はここ です

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

そして

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 :(!")
}

あなたはそれからこのようにそれを使うことができます

let message: String = .ThisApplicationIsCreated
print(message)

私にとってこれは最高です

  • ハードコードされた文字列は1つの特定のファイルに入っているので、変更したい日は本当に簡単です。
  • 毎回ファイルに文字列を手動で入力するよりも使いやすい
  • genstringsはまだ動作します
  • あなたは物事をきちんと保つためにView Controllerごとに一つのように、より多くの拡張子を追加することができます
5
Robin Dorpe

あなたがSDKを開発しているとき。追加の操作が必要です。

1)YourLocalizeDemoSDKでいつものようにLocalizable.stringsを作成します。

2)YourLocalizeDemoに同じLocalizable.stringsを作成します。

3)YourLocalizeDemoSDKのあなたのバンドルパスを見つけます。

Swift 4

// 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))は、YourLocalizeDemoSDKでバンドルを見つけるのに役立ちます。代わりにBundle.mainを使用すると、間違った値になります(実際にはキーと同じ文字列になります)。

しかし、 dr OX で言及されている文字列拡張子を使いたい場合。もう少しやる必要があります。 Originの拡張子はこんな感じです。

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

私たちが知っているように、私たちはSDKを開発しています、Bundle.mainはYourLocalizeDemoのバンドルのバンドルを取得します。それは私たちが望むことではありません。 YourLocalizeDemoSDKにバンドルが必要です。これはすばやく見つけるためのトリックです。

YourLocalizeDemoSDKのNSObjectインスタンスで以下のコードを実行します。そして、あなたはYourLocalizeDemoSDKのURLを取得します。

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

2つのURLの両方を印刷すると、mainBundleURL上にbundleURLofSDKベースを構築できることがわかります。この場合、それは次のようになります。

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

そしてStringの拡張子は次のようになります。

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: "")
    }
}

それが役に立てば幸い。

2
Liam

カスタム翻訳機能を使って文字列を抽出するための私自身のgenstrings種類のツールを作成しました。

extension String {

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

}

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

すべてのSwiftファイルを解析し、コード内の文字列とコメントを.stringsファイルにエクスポートします。

おそらくそれを行う最も簡単な方法ではありませんが、それは可能です。

1
Max

これは短縮の問題には答えませんが、メッセージを整理するのに役立ちましたが、以下のようなエラーメッセージの構造を作成しました。

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

これにより、メッセージを整理してgenstringsを機能させることができます。

これがgenstringsコマンドです。

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

単体テストでの使用に役立ちます。

これは単純なバージョンで、さまざまなユースケースに拡張できます(たとえばtableNameの使用など)。

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

このように使用してください。

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

またはコメント付きでこれを好む:

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

デフォルト言語によるローカライズ

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

翻訳するときは、フレーズが同じである英語から、それが異なる別の言語に変換する(性別、動詞の活用形または転置のため) Swiftで最も簡単なNSString形式は、すべての場合に機能し、3つの引数があります。たとえば、英語のフレーズ "previous was"は、 "weight"( "предыдущийбыл")の場合とロシア語に異なって翻訳されます。 "腰"( "предыдущбыл")。

この場合、1つのソースに対して2つの異なる翻訳が必要です(WWDC 2018で推奨されているXLIFFツールに関して)。 2つの引数NSLocalizedStringを使用してこれを達成することはできません。「previous」は、「key」と英語の翻訳(つまり値)の両方で同じになります。唯一の方法は、三引数形式を使うことです。

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

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

キー( "previousWasFeminine"と "previousWasMasculine")が異なる場合。

私は一般的なアドバイスは全体としてフレーズを翻訳することであることを知っています、しかし時々それはあまりにも時間がかかり不便です。

0
Vadim Motorine