LoginSignup
8
5

More than 3 years have passed since last update.

SwiftUIの多言語化

Last updated at Posted at 2020-11-23

概要

LocalizedStringKeyを使ってSwiftUIの多言語化を行います。

3行まとめ

  • Textに文字列定数を渡すと、文字列定数をキーにしてローカライズが行われます。XLIFFのエクスポートもサポートされます。
  • LocalizedStringKeyを使うと、引数をキーにして各種コンポーネントのローカライズ対応ができます。が、XLIFFのエクスポートはサポートされません。
    • NSLocalizedString をコメントの形としてつけておくとXLIFFのエクスポートに対応することが可能です。

Textの多言語化

Textのパラメータに、ダブルクォーテーションで囲われた文字列定数を設定します。
Export for localizationを行うと、Textの文字列を定数にしたものが全てXLIFFに出力されます。これをもって翻訳に使ったり、SwiftUIのプレビューから各言語の表示を確認できたりできます。

コード

SwiftUI

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))
    }
}

XLIFF

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 http://docs.oasis-open.org/xliff/v1.2/os/xliff-core-1.2-strict.xsd">
  <file original="l18/en.lproj/InfoPlist.strings" datatype="plaintext" source-language="en" target-language="ja">
    <header>
      <tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="12.2" build-num="12B45b"/>
    </header>
    <body>
      <trans-unit id="CFBundleName" xml:space="preserve">
        <source>l18</source>
        <note>Bundle name</note>
      </trans-unit>
    </body>
  </file>
  <file original="l18/en.lproj/Localizable.strings" datatype="plaintext" source-language="en" target-language="ja">
    <header>
      <tool tool-id="com.apple.dt.xcode" tool-name="Xcode" tool-version="12.2" build-num="12B45b"/>
    </header>
    <body>
      <trans-unit id="Hello, world!" xml:space="preserve">
        <source>Hello, world!</source>
        <note>No comment provided by engineer.</note>
      </trans-unit>
    </body>
  </file>
</xliff>

Textに定数を設定する場合以外

例えばLabelを使う場合などは、文字列の定数を設定したとしてもその定数をソースとしたXLIFFは出力されません。この場合、従来のコードで使っていたNSLocalizedString を使って対応することになると思います。

Labelのコード

SwiftUI

import SwiftUI

struct ContentView: View {
    let text = NSLocalizedString("Hello, world!", comment: "Hello, world!")
    var body: some View {
        Label(text, systemImage: "arrow.uturn.up")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))
    }
}

SwiftUIで言語のプレビューが効かない問題と解消法

しかし、NSLocalizedStringで対応を行なった場合、SwiftUIのプレビューでlocaleのenvironmentを切り替えたとしても言語の確認ができないという問題が発生します。
そこでLocalizedStringKeyを使います。

LocalizedStringKeyにキーを指定すると、SwiftUIのプレビューで確認ができるようになります。
ただし、LocalizedStringKeyもXLIFFのエクスポートに対応していないので、コメントの形としてNSLocalizedStringを書く形にするとXLIFFへのエクスポートにも対応できます。

SwiftUI

import SwiftUI

struct ContentView: View {
    // NSLocalizedString("Hello, world!", comment: "Hello, world!")
    let text = LocalizedStringKey("Hello, world!")
    var body: some View {
        Label(text, systemImage: "arrow.uturn.up")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))
    }
}

追記

LocalizedStringKeyのキーは、ローカライズされていない時にデフォルトで表示されるテキストになるので、多くの場合は表示される英語のテキストをキー名にしたほうがいいんじゃないかと思います。

OK

LocalizedStringKey("Hello, world!")

NG

LocalizedStringKey("hello_world")
LocalizedStringKey("helloWorld")
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5