Generating strings file with genstrings

Hey all,
I'm developing a fully programmatically app (not sure if it matters) and get to the point where I want to localize it.

Most of my strings are look like this:
Code Block swift
cell.label.text = localized("Hello world")

where localized() is just a wrapper around NSLocalizedString():
Code Block swift
func localized(_ string: String) -> String {
    return NSLocalizedString(string, comment: "")
}


So, I added desirable languages to my project and created *.strings file, but when I do
Code Block bash
find ./ -name "*.swift" -exec echo {} \; -exec genstrings -s localized -a -o Resources/en.lproj {} \;

I get a lot of errors:
Code Block
genstrings: error: bad entry in file ./bla-bla/myfile.swift (line = 30): Argument is not a literal string.


So, it seems that genstrings doesn't work with wrappers, though the man states:

  • s routine [-s routine ...]

Recognizes routine() as equivalent to NSLocalizedString(). For example, -s MyLocalString will catch calls to MyLocalString(), MyLocalStringFromTable(), and so on.
Am I missing something? Is there any way to generate a strings file except looking for some better tools on GitHub/creating my own?




I believe the function signature of localized will need to match the function signature of NSLocalizedString for genstrings to pick up the strings from code. Our recommendation is that you should always include in a comment to localizers for context; hence why this property is required for NSLocalizedString in Swift.
A suggestion.

Instead of the func, you could define String extension, with a property or a func

Code Block
extension String {
var localized: String {
NSLocalizedString(self, comment: "")
}
mutating func localize(comment: String = "") -> String {
NSLocalizedString(self, comment: comment)
}
}

then you can call myString.localized or myString.localize() or myString.localize(comment:"Some comment")

Code Block
print("hello".localized)
var myString = "hello you"
myString = myString.localize(comment: "Some comment") // or myString = myString.localize() without comment
print(myString)


I believe the function signature of localized will need to match the function signature of NSLocalizedString for genstrings to pick up the strings from code. 

I have re-made my function:
Code Block
localized(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String = "") -> String

Still getting the same errors :(

Our recommendation is that you should always include in a comment to localizers for context; hence why this property is required for NSLocalizedString in Swift.

Thanks for the advice, but it's a deliberate decision. I am a localizer for the app.


Instead of the func, you could define String extension, with a property or a func

I thought about it, but writing "bla-bla-bla".localized looks ugly for my taste.





writing "bla-bla-bla".localized looks ugly for my taste. 

You're right, that's a question of taste.

But there are already a lot like this in StringProtocol:
"bla-bla-bla".localizedUppercase
or
"bla-bla-bla".localizedCapitalized

If you need to keep your func, why not change it as:

Code Block
func localized(_ string: String, comment: String = "") -> String {
NSLocalizedString(string, comment: comment)
}

Doing so you can still call:
Code Block
cell.label.text = localized("Hello world")

NSLocalizedString() can't be used un a function like that, because it's a macro. If you have two strings to localize you need to have two separate NSLocalizedString() macros in the code containing those strings. This way genstrings would be able find them in the code. The way you wrote it, all genstrings can see is one entry.

Generating strings file with genstrings
 
 
Q