Swift

Swiftで genstrings を使いつつ NSLocalizedString を安全に使う

More than 1 year has passed since last update.

genstringsを使いつつNSLocalizedStringを安全に使う方法をいろいろ考えていたのだが、一つ思いついたので書き記す。

ソース

Localizable.swift
import Foundation

protocol Localizable {

    var key: String { get }
    var table: String? { get }
    var bundle: Bundle { get }
    var comment: String { get }

    var string: String { get }
}

extension Localizable {

    var string: String {

        return NSLocalizedString(key, tableName: table, bundle: bundle, comment: comment)
    }
}

struct LocalizedString: Localizable {

    let key: String
    let table: String? = nil
    let bundle: Bundle = .main
    let comment: String


    init(_ string: String, comment: String) {
        self.key = string
        self.comment = comment
    }
}

struct LocalizedStringFromTable: Localizable {

    let key: String
    let table: String?
    let bundle: Bundle = .main
    let comment: String


    init(_ string: String, tableName: String, comment: String) {
        self.key = string
        self.table = tableName
        self.comment = comment
    }
}

// これはなくていい。というかない方がいい?
struct LocalizedStringFromTableInBundle: Localizable {

    let key: String
    let table: String?
    let bundle: Bundle
    let comment: String


    init(_ string: String, tableName: String, bundle: Bundle, comment: String) {
        self.key = string
        self.table = tableName
        self.bundle = bundle
        self.comment = comment
    }
}

// NSLocalizedStringWithDefaultValue を使う人はここに書くんだ! 僕は使わない!!!
LocalizedStrings.swift
struct LocalizedStrings {

    static let Hoge = LocalizedString("Hoge", comment: "Hoge Comment")
    static let Fuga = LocalizedStringFromTable("Fuga", tableName: "TableA", comment: "Fuga Comment")
    static let Piyo = LocalizedStringFromTableInBundle("Piyo", tableName: "TableB", bundle: Bundle(for: NSObject.self), comment: "Piyo Comment")
}

注意

Localizable.swiftとLocalizedStrings.swiftは必ず2つのファイルに分けてください。
genstringsがクラッシュします。

使用法

ローカライズ用stringsファイルの生成

下のコマンドを実行することでローカライズ用stringsファイルが生成される

genstrings -s LocalizedString LocalizedStrings.swift

テーブル名が同じならバンドルが別のものでも一つのファイルにマージされます。

ローカライズされた文字列の取得

let localized = LocalizedStrings.Hoge.string

でローカライズされた文字列が取得できる。

LocalizedStringsに必要な値を追加して行く。(別にLocalizedStringsに追加でなくてもいい)

おもったこと

genstrings

swiftとgenstringsを組み合わせて使ってる人っているのだろうか。
というかgenstrings自体使っている人いるのだろうか。
甚だ疑問である。

swiftだとCの関数の形式でさらにラベルがつくのでgenstringsが使えそうにないのに使えてしまうのは、バグなのか、仕様なのか、なんなのか。