📖
SwiftPM(Package.swift)でString Catalogs(Localizable.xcstrings)を使う方法
String Catalogs(Localizable.xcstrings)
Xcodeで作成したApp.xcodeproj
内でLocalizable.xcstringsを追加するとSwiftUI.Textで使われた文字列はLocalizedStringKeyとして認識され、ビルドすると自動でString Catalogsに追加されるため、自分で値を追加する必要がありません。
WWDC 2023で発表され、Xcode 15.0から利用可能です。
SwiftPM(Package.swift)では一工夫必要
直接App.xcodeproj
にLocalizable.xcstrings(リソース)を追加するとBundle.mainに追加されます。しかしSwiftPM(Package.swift)に追加するとBundle.moduleにリソースが追加されます。
SwiftUI.Text
のinitにbundleを渡せるのですが、デフォルトでnilになっています。
nilだとBundle.mainを参照するため、SwiftPM(Bundle.module)内にあるLocalizable.xcstringsに自動で追加してくれません。
.init(
_ key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle? = nil,
comment: StaticString? = nil
)
セットアップ
Package.swift
defaultLocalizationの設定が必要
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "SampleApp",
defaultLocalization: "en",
platforms: [
.iOS(.v18),
],
products: [
.library(
name: "SampleApp",
targets: ["SampleApp"]
),
],
targets: [
.target(
name: "SampleApp"
),
]
)
Localizable.xcstrings
String Catalogs(Localizable.xcstrings)を追加
Text++.swift
デフォルトでBundle.moduleを参照するinitをextensionで作成して、元々あったinitをデフォルトで呼ばれないようにする。
import SwiftUI
extension Text {
init(
_ key: LocalizedStringKey,
tableName: String? = nil,
comment: StaticString? = nil
) {
self.init(
key,
tableName: tableName,
bundle: .module,
comment: comment
)
}
}
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello!")
}
}
#Preview {
ContentView()
}
#Preview {
ContentView()
.environment(\.locale, .init(identifier: "ja_JP"))
}
ソースコードに直接指定
LocalizedStringKeyを直接持つことで、自動でString Catalogsに追加してくれます。
enum TabItem {
case favarites
case recents
case contacts
case keypad
var title: LocalizedStringKey {
switch self {
case .favarites: "Favorites"
case .recents: "Recents"
case .contacts: "Contacts"
case .keypad: "Keypad"
}
}
}
Discussion