Automating UIStoryboard localizing without duplicating .storyboard files - ios

So far, I used to manually create a localization file for storyboards texts, writing a line like this one for each UILabel / UIButton.-
"ACCESS" = "ACCESS";
and translated them with a similar function such as the proposed here.-
Storyboard/XIB and localization best practice
I've just found a nice tutorial to automate xibs and storyboards localization.-
http://kb.applingua.com/2011/10/extracting-and-localizing-xibs-ibtool/
which uses ibtool to automate the localization files creation (a huge step indeed), BUT needs to duplicate storyboard files to 'import' the new localized labels. I don't want to duplicate my storyboards and do any change twice from now on, but function on the first thread won't work with the automatically generated files, since the generated texts are like this.-
"Qa1-zu-aC4.normalTitle" = "ACCESS";
The first approach I can think of is manually updating the generated files (still, I'd save some time, but it'd be painful as well).
Is there any way to use the automatically generated files to translate the application on runtime without duplicating storyboards?
EDIT
Just found a workaround using regex to transform
"Qa1-zu-aC4.normalTitle" = "ACCESS";
into
"ACCESS" = "ACCESS";
The regex looks like this.-
Find "([^"]*)" = "([^"]*)";
Replace "\2" = "\2";

Related

XLIFF doesn't contain all forms of plurals when trying to localize a project in Xcode

I'm trying to localize a small Xcode project (Xcode 9 and Swift 4). In that project there are places where I use plurals, so I need to localize them, too. To do that, I use stringsdictfile. In code I use localizedStringWithFormat(_:,fromat,:argument) static method on a String. Here how my code for a plural looks (I just print the words for testing):
let localizedString = NSLocalizedString("%d apple(s)", comment: "The number of apples")
print(String.localizedStringWithFormat(localizedString, 0))
print (String.localizedStringWithFormat(localizedString, 1))
print(String.localizedStringWithFormat(localizedString, 2))
print(String.localizedStringWithFormat(localizedString, 10))
Then I create a stringsdict file. It looks like this:
In the video from WWDC 2017 (session 401) about Localization it is said, that when we use stringsdict file for localizing plurals into other languages (in this case, I want to localize it into Russian) we just need to give values for the cases of our development language (English), and when exporting for localization, Xcode will automatically create cases in an XLIFF file for the language into which we want to localize. So I've given values for zero, one and other (in the demo from the session values are given only to keys one and other, however, I don't thing that that's the reason of the problem).
Now, when I create an XLIFF file it looks like this (only the part of apples):
As you can see, Xcode doesn't generate cases for a particular language automatically (for Russian it should have 4). I'm using stringsdict files as well as trying to localize plurals for the first time, so I can't figure out what I'm doing wrong. If you know where is the issue, or have any suggestions, I would appreciate your help.
There is little you can do in Xcode. XLIFF just holds the segments that it's been told to hold.
A better approach would be to rephrase the strings so that plurals are less an issue, like:
not "%d apple(s)"
but "number of apples: %d"
You should file a bug at apple about that.
Unless you have a requirement to work with the XLIFF from Xcode, I suggest you don't and instead rely on the string files.

NSLocalizedString in Spritekit SKLabelNode

I've been searching all over the internet and there doesn't seem to be a clear explanation on how to localize strings using SpriteKit. Only seeing tutorials for people using the interface builder, but all I really want is, imagine this:
I have an SKLabelNode called label. And I define the text like:
labl.text = NSLocalizedString("titleOfTheScreen",nil)
So basically what I think I have to do is add the new language in the Project settings. Then, I add a new Strings file called Localized, and add it to the new folder.
But what happens to my English language? There's no file for the original one
First you have to add a Strings File:
Then open the project settings and add a new language:
Mark your added strings file as target:
Find the newly added localising file. (English is automatically added)
From your screenshots I can see that you have "File.strings" file. You should have created "Localizable.strings" file.
Also, I can see that you have the (Base), (English) and (German) strings version. Why do you think English is not there?
In each of the files you should put strings like that:
"titleOfTheScreen" = "blah-blah";
Replace "blah-blah" with the proper translation in each of the strings files. It's important to note that the semi-colon at the end of the lines in strings files are mandatory, otherwise Xcode would issue some really funny error messages. This is easy to overlook if you're programming in Swift and trailing semi-colons are not mandatory.

iOS Storyboard Localization: Manually editing generated files

I'm in the process of localizing an iOS application. I've run into a few issues though - the main one being storyboard localization. I need to add textual context to each string so that the translator can understand how the string is used. For example, in my storyboard localization for English, I will change:
/* Class = "UILabel"; text = "Label"; ObjectID = "1Sf-fE-WR8"; */
"1Sf-fE-WR8.text" = "Label";
to:
/* Context: this label is the header of the settings screen */
"1Sf-fE-WR8.text" = "Label";
Firstly - is this a bad idea? The problem is that if I ever have to re-generate the localization for the storyboard, all edits I've done on the file will disappear. How then, in the future, if I add a new element to the storyboard, will I get that element into the .strings file without regenerating it?
Note:
a) I have tried "Export For Localization", but this always results in an error "Localization failed to read a strings file"
b) The project is set up in a strange way: there is a parent project which has existing localizations, and we've added a sub-target which has it's own localized files, but the overall localization export mechanism applies to the project as a whole, and I'm worried that fiddling with it will corrupt the existing work.
Any help or thoughts are appreciated!
There's a "Comment for the localizer" text field that you can use to provide the label's usage context.
Not sure if it's still relevant to you or if it was present back in the days of Xcode 7.

How to get the "Created by <name> on <date>" text

So the question is actually simple, but I have no idea how to approach this issue. I know this code is generated by template based on this question:
XCode automatically generated comments?
I want to use the <name> that xcode provides on each mac machine which is unique for it's user, for some types of logs.
EDIT:
This is how the swift template file looks before it's used by Xcode to create my work file:
//
// ___FILENAME___
// ___PROJECTNAME___
//
// Created by ___FULLUSERNAME___ on ___DATE___.
//___COPYRIGHT___
//
Surely, there is no point in parsing it.
The question is: Does anyone knows how I can get this name using swift in my application?
I searched for an answer here/Google but so far no luck.
I don't know how to read the header. But you can do it otherwise.
First if you need the creation-date of a file, you can use the NSFileManager:
var path = "path/to/your/file/"
var fileAttribs:NSDictionary = NSFileManager.defaultManager().attributesOfFileSystemForPath(path, error: nil)!
var creationDate = fileAttribs.objectForKey(NSFileCreationDate)
Also if you need the full username, you can use the function NSFullUserName() or NSUserName(). It should return the same string as __FULLUSERNAME__
var fullUsername = NSFullUserName()
var username = NSUserName()
Sometimes in the iOS Simulator, this username is empty, but in a real app, it should work properly.
That text written at template instantiation time — that is, when you create a new Xcode project (or a new file in an existing project using the File > New > File... templates). You can't read the contents of the source file your code was compiled from. (Well, unless you ship that file along with your compiled binary, and read it in like any other text file.)
But that's just text substitution — it can be done anywhere in the file, not just in the comment headers. So you could create your own file or project templates, and in the template files, put those substitution macros in code instead of in comments:
let schmoeWhoCreatedThisFile = "___FULLUSERNAME___"
Here's a tutorial found in a couple seconds of web searching that has the full details on creating templates and the substitution macros you can use in them.
Remember, substitution happens when you create a new file or project — if you're looking for who made the latest change to your source file or who built the app that shipped to your customers, you're barking up the wrong tree. Some of those sorts of things you can do with source control; others are more a matter of (human-defined, human-executed) policy for you or or your organization.

How to make UILabel contents non localizible when genetating string via ibtool?

I have some labels on my xib. Some of them are not need to be localized. When i generate strings file via ibtool all labels content included in result file.
How can i exclude some UI objects in IB from localization when generate strings?
Unfortunately there is no way to annotate the content of your nib/xib files so that ibtool's --export-strings-file command ignores certain strings.
You could instead opt to use the --export-xliff option and then edit the XLIFF file to lock segments that must not be translated (attribute translate="no") before sending them out to be localized in all your languages. That's probably only worth doing if the localizers use a XLIFF-compatible CAT tool though.

Resources