String resources Xcode + swift - ios

I am new in iOS developing and in Swift language.
And I try to make simple iOS application, and I need to have some string resources (for labels and text fields) in app. Of course, I can put this strings to my *.swift files as constants, but I think, it is a bad way. How can I do it? I need something as string resources in Android. I use Xcode 6 beta with swift.
TY for answers ;)

Your best bet is creating a file called Localizable.strings. In this file you can make localised string variables you can use throughout your application.
Define strings like this;
"hello_world" = "Hello World!";
Use them in your Obj/C code like so;
NSLocalizedString(#"hello_world", nil);
Or in Swift;
NSLocalizedString("hello_world", comment: "")
p.s., I haven't tested this. Swift code might be faulty because of the fact I can't test this atm.

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.

XLIFF file, keys and long strings with NSLocalizedString

I want to move to xliff instead of translating Localizable.strings and Main.strings files but I found out that I'm using NSLocalizedString in an improper way (and I did it for 5 years actually...).
I don't like to have the translations directly inside my code, so I use a generic key and I do not write any comments:
NSLocalizedString("general.error", comment: "")
Then I include the string into the Localizable.strings
"general.error" = "An error occured";
So far so good (maybe). Now when I export xliff files I see that the source is just my generic key and obviously a translator cannot guess what to write as target for that key :/
So my question is: Is the only solution to move all the translations directly inside the NSLocalizedString?
NSLocalizedString("An error occured", comment: "")
or inside the comment... (I really don't like this solution)
And what if the string is really long? it seems so strange to put a string of 3 rows directly into the code :/
Any other interesting solution out there?
EDIT
I've already tried to use constants, but it seems that this solution doesn't work in swift. I've created a String.swift file where I've added constants:
let thisIsMyLonStringID = "An here I can put the long translation";
And I can use it in this way:
NSLocalizedString(thisIsMyLonStringID, comment: "")
When I export to XLIFF this string is not available in the xliff files though :(
I put here an answer with my temporary solution. It seems to work pretty well actually.
Instead of using a Base language for the Localizable.strings file I've used English, so I've just deselected Base from the file inspector -> Localizations area in Xcode and I've been prompt with a question like "which language would you like to use as base"... I've selected english.
Now I can continue using NSLocalizedString using a generic key and putting the translations in Localizable.strings when I export to xliff automatically the source is filled with the right translation and not with the key.
You need to make the call to NSLocalizedString directly in your Strings.swift file. For example:
// Strings.swift
let myString = NSLocalizedString("some very long string", comment: "")
// Usage
print(myString)
That way, the string export process will be able to determine the string literal that is passed in to NSLocalizedString.
Yes there is very elegant solution to your problem. Problem is very long string's are getting part of our code, making it harder to read and messy.
Solution:
Create LocalizationKeys.h
#ifndef Project_LocalizationKeys_h
#define Project_LocalizationKeys_h
static NSString *const LocalizationKeyForVeryLongString =
#"Your Very Very Long String";
#endif
In your code: ViewController.m
NSLocalizedString(LocalizationKeyForVeryLongString, "");
So above solution separated very long messy strings and replaced them with elegant and readable Key Strings, moreover now we have separate file for key strings, so whenever someone is needed to change or to lookup, directly refer to LocalizationKeys.h

How does one use namespaces in iOS objective-c code?

I'm writing an iOS app, "Best Korea". My organization name is "Srsly.co". I'm going to write re-usable "News" libraries that I'll use across my apps.
Each iOS app will have its own app-wide constants in a .h file, and the library code will have its constants as well in header files. I'll also have tests for each of these projects.
Is this the standard way of doing things?
In Ruby, Python, Java, etc., I'd set up namespaces along these lines:
co.srsly.bestkorea
co.srsly.bestkorea.test
co.srsly.newslib
co.srsly.newslib.test
As far as I can see, the Objective-C pattern is for each developer to choose two or three upper-case letters and prefix every class name with them.
So in my case, I'm thinking I'd choose BK as the app's classname prefix and NL for the news lib code? Am I thinking about this the right way?
EDIT: I'm considering not using namespacing at all in my application code as discussed here.
You're correct that Objective-C doesn't have built in support for namespaces, and the common solution is to use uppercase prefixes on each class. Note that Apple has stated that two letter prefixes are reserved for their use, so you should use three letter prefixes for your own classes. Otherwise, your suggested approach is the normal thing to do.
There is no NameSpace in Objective-C as you are expecting in Java.
Objective-C uses class Prefix like NS, UI, CG, CF etc to safely remove name space collision.
And it would be better to use 3 letter Prefix for your class.
You should read this : What is the best way to solve an Objective-C namespace collision?

Best way to utilize strings in iOS

I am new to coding in Objective-C, but am coming from the Java world of mobile development. In Android, we use a strings resource, and then point to those in the Java class. Is there an analogous process in iOS that we should be using, or do we "hard-code" the strings into the implementation files? I haven't yet found a good tutorial using the localizable string (and .strings) file.
You can use the NSLocalizedString macro from Foundation to retrieve a localized string. Read here:
http://www.icanlocalize.com/site/tutorials/iphone-applications-localization-guide/
Example: build a bilingual (English-French) app.
Whenever you encounter a string to be displayed to the user, use NSLocalizedString instead of the actual string constant. For example:
instead
self.title = #"Welcome";
use
self.title = NSLocalizedString(#"Welcome");
Create two directories inside your app bundle as follows:
MyApp.app
English.lproj
Localizable.strings
French.lproj
Localizable.strings
In the first Localizable.strings file you can write key-value pairs like this:
"Welcome" = "Welcome";
In the second one:
"Welcome" = "Bienvenus";
When you add these files and folders to your application, an recompile it using the NSLocalizedString macro, you'll be able to use your app in French also when the system language is French.
Sure, there's a way to do that.
Take a look at the Apple doc here - http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
There's not much more to it than that really. Although I tend to just hard code a lot of strings but it's definitely worth taking the time to learn about string resources because it's the basis of internationalisation.

Resources