我正在创建快速应用程序。它包含Localizable.strings文件中的某些字符串。每次我要使用它时,都需要通过其ID获取它。一开始,我与他们创建了一个枚举,但是每次添加新文本时手动添加它有点烦人。
我试图简化此过程,并向xcode构建阶段添加了新的脚本阶段。该脚本为我创建了字符串扩展类,然后逐行读取可本地化的文件,在引号之间找到单词并将其转换为字符串变量。总的来说,如下所示:
echo "
import Foundation
extension String {
" > Classes/Constants/StringId.swift
while IFS= read -r line;do
PREFIX="static var"
VAR_NAME=`echo $line| awk -F \" '{print $2}'`
SUFFIX_1=": String {
get {
return String.from(core: \"$VAR_NAME\")
}}"
SUFFIX_2="\""
if [ -z "$VAR_NAME" ]
then
echo "empty"
else
echo "$PREFIX lib_$VAR_NAME $SUFFIX_1" >> Classes/Constants/StringId.swift
fi
done < Resources/Base.lproj/Localizable.strings
其中String.from ...是我从适当的资源文件中获取字符串的内部方法(例如常规字符串,可访问性字符串或可烙印的字符串)。
结果,我有一个具有以下结构的类:
import Foundation
extension String {
static var lib_author_website : String {
get {
return String.from(core: "author_website")
}}
static var lib_author_name : String {
get {
return String.from(core: "author_name")
}}
static var lib_app_name : String {
get {
return String.from(core: "app_name")
}}
}
最后,我可以像这样调用字符串:
label.text = String.lib_app_name
这只是我的主意,但我需要自己做所有这些,所以我只是想知道是否有更好或更流行的解决方案?我计划对资产名称和情节提要进行相同的操作,但也许有更好的方法来处理此问题?
最佳答案
dr_barto对。 SwiftGen是从字符串文件生成代码的好工具。
细节
解
播客文件
target 'stackoverflow-46981208' do
use_frameworks!
pod 'SwiftGen'
end
运行脚本
TemplatePath=$PODS_ROOT/SwiftGen/templates
AppRoot=$PROJECT_DIR/stackoverflow-46981208
Resources=$AppRoot/Resources
LocalizationInput=$Resources/Localization/en.lproj/Localizable.strings
LocalizationOutput=$Resources/Localization/GeneratedStrings.swift
$PODS_ROOT/SwiftGen/bin/swiftgen strings $LocalizationInput -p $TemplatePath/strings/structured-swift4.stencil --output $LocalizationOutput;
文件结构
Localizable.strings
"Basic.Hello" = "Hello";
"Auth.SignIn.Login" = "Login";
"Auth.SignIn.Password" = "Password";
用法
print(L10n.Basic.hello)
生成的代码样本
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Strings
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name
internal enum L10n {
internal enum Auth {
internal enum SignIn {
/// Login
internal static let login = L10n.tr("Localizable", "Auth.SignIn.Login")
/// Password
internal static let password = L10n.tr("Localizable", "Auth.SignIn.Password")
}
}
internal enum Basic {
/// Hello
internal static let hello = L10n.tr("Localizable", "Basic.Hello")
}
}
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:enable nesting type_body_length type_name
// MARK: - Implementation Details
extension L10n {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
// swiftlint:disable:next nslocalizedstring_key
let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
return String(format: format, locale: Locale.current, arguments: args)
}
}
private final class BundleToken {}
结果