Reputation: 500
I'm creating swift application. It contains some of the strings in Localizable.strings file. Each time when I want to use it I need to get it by its id. At the beginning I created an enum with them but it was a little bit annoying to add it manually every time when I add new text. I tried to make this process simplier and I add new script phase to the xcode build phases. This script create for me string extension class and then read the localizable file line by line find words between quotes and convert it to the string variable. In general it looks like following:
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
Where String.from... is my internal method to get string from properly resource file (like general strings, accessibility strings or brandable strings).
As a result I have a class with following structure:
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")
}}
}
And finally I can call the string like:
label.text = String.lib_app_name
It is just my idea but I needed to make all of these by myself, so I just curious if there is better or more popular solutions for it? I plan to do the same for the assets names and the storyboards but maybe there is better approach for handle this?
Upvotes: 1
Views: 7181
Reputation: 25294
dr_barto right. SwiftGen is a good tool to generate code from strings files.
Podfile
target 'stackoverflow-46981208' do
use_frameworks!
pod 'SwiftGen'
end
Run Script
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;
Files structure
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 {}
Upvotes: 5
Reputation: 6085
You can use SwiftGen to auto-generate code for type-safe access to various projects resources, amongst others also for localizable strings. It even supports placeholders inside the strings. The tool can be run standalone on the commandline or integrated into the project's build process, so that every time you compile you also get updated localization code.
Upvotes: 0