A while back I was thinking about one of our workflows. When it comes to iOS localization, the way it was prior to Xcode 6 was to either use genstrings, which sucks, or come up with your own in house solution, which sucks.
One problem with the old genstrings was that it would overwrite all of your strings. That’s fine if you’re going to send all of your strings out for translation every single time. However, if you’re having rapid releases, you may not be willing to pay to get the same string translated again and again. You also might not be able to deal with the extra overhead of the number of strings to translate.
Another problem with genstrings, and this is a huge problem, is that you have to use the full string in code. Here’s what I mean:
1 |
NSString* string = NSLocalizedString(@"Hello World", nil); |
genstrings will create this
1 |
"Hello World" = "Hello World"; |
As everyone should know, NSLocalizedString uses key value pairs. In this case “Hello World” is the key and the value. That’s how genstrings expects you to do it. This is ok if you want to ruin your life. As soon as you get to bigger strings, you can run into huge issues.
You may have something like this in the event of a catastrophic failure.
1 |
NSString* string = NSLocalizedString(@"An unrecoverable error has occurred while uploading attachments. Please quit the app and ensure that you have free disk space and try again. If you have any further issues, please contact customer support.", nil); |
If you have that beast of a string as the key, there are so many possible places to go wrong. Misspell a word, capitalize something, put in an extra space, leave a space out. There are so many places to go wrong. When using your app in your development language, you could have never noticed, but then you run it in Spanish, and suddenly there’s random English sentences all over the place.
I will admit that if you’re using genstrings and sending all of your strings out for translation every single time, you are less likely to run into this issue, but still. It’s a lot nicer to do something like this
1 |
NSString* string = NSLocalizedString(@"upload.unrecoverable_error", nil); |
You’ve got the string “namespaced” so you don’t have to worry about conflicts in key names, and you’ve got something short to use in code.
For this reason Xcode 6’s XLIFF output is a great way to go. You can use anything you want for the key, and when you export, you can decide if you want all of the strings to come from your development language, or if you want to keep your existing translations and export a mixed file.
Unfortunately Xcode’s XLIFF output is still flawed in some major ways (in my opinion) but with a little scripting, you can do so much.