NSLocalizedString not getting value for the key - ios

I have a 2 localized string files, one for Romanian and one for English. In both files I have this line:
English:
"invalidSum" = "Invalid amount"
Romanian:
"invalidSum" = "Suma invalida"
I use this message in a alert like this:
let titleAlert = NSLocalizedString("invalidSum", comment: "")
let sumAlert = UIAlertController(title: titleAlert, message: nil, preferredStyle: .alert)
sumAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(sumAlert, animated: true, completion: nil)
}
However, whenever the alert shows, I get the message "invalidSum", not "Invalid amount" for english localization and "Suma invalida" for romanian localization. What am I doing wrong?

Rename your Localized.string file to Localizable.strings. That's it.

Solved it
My issue was that I created those new strings into Main.strings file (The files that Xcode automatically creates for you when you select new languages in Project Info.
I had to create 2 new Strings file called "Localizable.strings" and Localize it one for english, one for romanian. I copied the strings I've written into Main.strings to Localizable.strings and now it works like charm.

The name for the localizable file should be "Localizable.strings".

In my case, the problem was in an incorrect format.
The problem did not arise immediately, but only after the next build cleanup (or tms like that).
So, I found that lines from the end of the file are not translated, but from begin are.
And I turned out that one of the lines looked like
= "some value";
That is, there simply was no key. And the build was going without errors. But all the lines below were not translated.

Related

NSLocalizedString always returns capitalized text

Ive run into an issue where NSLocalizedString is always returning strings capitalized regardless of its input. localization was working
and Im assuming I did something that caused this but I cannot seem
to figure out exactly what changed.
Here's my code:
func localize(_ str: String) -> String {
print("str in: \(str)")
return NSLocalizedString(str, comment: "")
}
I call it like this:
let txt = self.localize("Question")
print("txt = \(txt)")
Output:
str in: Question
txt = QUESTION
Things Ive tried:
Ive grep'd all of my .strings files and confirmed there is no
'QUESTION' in there.
Removed app from Simulator and re-run app
Changed incoming string to something that doesn't exist in any file such as 'randomxxyxxy'
Ive tried searching for quite a while on this issue and wasn't able to find anything that was like this problem.
Any help is appreciated,
Thank you
When your app is trying to localize a string but cannot find the translated text for it then it will show it in capitals. This is done to show you that the capitalized text is not localized. You can disable the capitalization of those cases by disabling the option: Show not-localized strings
This is how you do that:
Edit the scheme
Select the “Run” action and click the “Options” tab
Uncheck the “Show non-localized strings” option
In your case I think that your strings' localization is not working and so they are capitalized because that setting is activated.

iOS - only one localization works

I try to localize my project. I have clicked "Use Base Internalization" and added 2 languages: English and French. The English is marked as "Development language" - not sure, maybe I set it, but in the storyboard I use another language (not English). And second difference between these 2 localizations is that English (Development language) has 2 files localized while French has only 1 file localized (screenshot) I checked the app's folder. In the en.lproj
there is only 1 file Main.strings with all my english translations. In the fr.lproj the same thing - only Main.strings but with french translations.
So in the folders everything is correct, but:
1) When I run app with English language - everything works correct. But when I set French language to simulator (or my real device, after deleting the app) nothing works - it shows me my standard storyboard (not English).
2) English localization has 2 localized and I can't understand what is the second file.
The second point is not crucial for me now. I just need to make French localization work
When you add Localization than these file will show
Localizable.strings (English). “Hello ” = “Hello”; (Ex you can write hello )
Localizable.strings (Frech). “Hello ” = “Bonjour”;
Or main string you can change object into freach
Main.strings(English). 3ZR-e4-Gil.text" = "Hello";
Main.strings(Frech). 3ZR-e4-Gil.text" = "Bonjour";
swift
import Foundation
extension String {
func localized(lang:String) -> String {
let path = Bundle.main.path(forResource: lang, ofType: "lproj")
let bundle = Bundle(path: path!)
return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
}
}
let str = "Hello".localized(lang: self.language! )
change language via simulator
Or Programmatically change language via app
UserDefaults.standard.set(["en","fr"], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
SOLVED IT!!! The French localization wasn't used because there was a mistake in the Main.strings (for French) - I missed only one ("). But as in the Main.strings there is no catcher for such a mistakes I didn't get it.
So, it was: "XXX-6r-aEC.text" = "Confirmer;
and I changed it to:"XXX-6r-aEC.text" = "Confirmer**"**;

Localizable.strings is not working

I added a Localizable.strings to my project, but its not working... Here is a sample:
NSLog(#"Welcome Text: %#", NSLocalizedString(#"WelcomeKey", #""));
The Localizable.strings:
Localizable.strings // DE
"WelcomeKey" = "Willkommen!";
and
Localizable.strings // EN
"WelcomeKey" = "Welcome!";
The Localization native development region is en
The NSLog in console is:
2013-05-11 04:45:49.552 App[13752:907] Welcome Text: WelcomeKey
Any ideas what's wrong ?
The localization from the Storyboard is working.
Codierung of both files are UTF-16
Have you added a strings file to store the localized text. Click File > New > New File.
This link will be helpful to you. Please check this localizable strings.
I found this answer maybe helpful to you:
Select the localized storyboard eg. Chinese (Simplified)
In File Inspector, toggle from “Localizable Strings” to “Interface Builder Cocoa Touch Storyboard”. This will retain the strings you already had, so you don’t have to worry.
Now, change it back to “Localizable Strings”, and things should be updated!
Here to view original tutorial

Create localizable.strings from Code in iOS

I'm currently localizing my iOS-Application. This works pretty decent so far.
I've already created localizable.strings and several xib-files and so about 80% of the app is already translated.
But the App also loads data from a WebService which passes me a key, e.g.: "TITEL 1" as well as all supported languages (values) attached to it e.g: "Titel One" "Titel Eins" "Titolo Uno".
And now i would like to store those values in the according localizable.strings files.
For example:
Localizable.strings (English) should then contain:
"TITLE 1" = "Title One";
Localizable.strings (German) should then contain:
"TITLE 1" = "Titel Eins";
Localizable.strings (Italian) should then contain:
"TITLE 1" = "Titolo Uno";
How can I do this?
You will not be able to insert them in the localization strings at run time, if the webserver is managed by you, i suggest that you send wich language is the user using,
Please consider this example
//Get the language code
NSString* languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
//Now send the request to the server with the language you want
NSString *str = [NSString stringWithFormat:#"www.yourserve.com/yourfunctiom?lang=%#", languageCode];
//Request it
Now basing on the language that you receive in your server you will return the appropriate string
This may be stretching the frameworks a bit, but if you want to use Apple's string loading functions you could try to build an NSBundle in your document directory (a bundle is just a directory, after all), fill it with files from the server and then use NSLocalizedStringFromTableInBundle to get to your strings.
Not sure it is worth it compared to the approach in Omar Abdelhafith's answer, though.

NSLocalizedString only retrieves the key, not the value in Localizable.strings (IOS)

I've made a strings file named "Localizable.strings" and added two languages to it, like so:
"CONNECTIONERROR" = "Check that you have a working internet connection.";
"CONNECTIONERRORTITLE" = "Network error";
I have also converted the files to Unicode UTF-8
However, when I create a UIAlertView like this:
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"CONNECTIONERRORITLE",nil)
message:NSLocalizedString(#"CONNECTIONERROR",nil)
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
the alert view only shows the key text, not the value. It works if I, for example, set a UITextviews text to NSLocalizedString(#"CONNECTIONERROR",nil), but the alert view only displays the key. Anyone know what's wrong?
In my case it was because I had mistakenly named the file "Localization.strings" and hadn't noticed (it has to be named Localizable.strings). As explained previously the symptom is because the compiler cannot find the string. Otherwise the cause could be any number of things but usually it's a missing semi colon or quotation mark. These are hard to find when you're doing a lot of localizations at once. The lesson learned is to start building your localization file early on in your development process and build it as you go, so that they are easier to spot.
Same problem, solved using the filename: Localizable.strings
Change your .strings file name to Localizable.strings, it worked for me.
Double check that the Localizable.strings file is being added to
Targets -> BuildPhases -> Copy Bundle Resources
It hadn't been added automatically for me.
Edit 2021: with XCode 12 the Localizable.strings have to be added to
Targets -> Build Phases -> Compile resources
I have been searching the solution for 5 hours, I tried everything I could to make my app localization working.
The problem was that one of the Pods of my project had a Localizable.strings file (actually it was Parse pod that had not renamed it). Therefore my Localizable.strings file was not recognized by my app.
I fixed the issue by changing the name of the file to "MyappnameLocalizable.strings" and using NSLocalizedString this way:
NSLocalizedString("key", tableName: "MyappnameLocalizable", comment: "comment")
Tested the app on an actual device and it worked
I was having problems with this on the iOS Simulator. I ended up deleting the Localization.strings file in the simulator directory
( /Users/(me)/Library/Application Support/iPhone
Simulator/5.0/Applications/(etc)/(project)/(application.app)
cd to there and delete all copies of Localization.strings found there.
For some reason the usual rubber chicken voodoo of build clean, quit iOS Simulator, quit XCode, etc wasn't working, but this did. At least for me, today.
This is happening when the runtime can't find the specified key, for whatever reason. In your case, it's most likely due to a typo: CONNECTIONERRORITLE is missing a T for TITLE. Also pay attention to any warnings/error when compiling regarding the Localizable.strings file: if there are unbalanced " or missing ; the file cannot be compiled/read correctly.
Change the name of the file to Localizable.strings, make sure the target in the file inspector is set.
To avoid syntax errors right click on Localizable.strings file->open as->ASCII property list
Also, cleaning the project and building again helped in my case.
NSLocalizedString usage means you need the EXACT case and spelling of your key in order to get the content from it. You'll notice that this one says
NSLocalizedString(#"CONNECTIONERRORITLE",nil)
when it should be
NSLocalizedString(#"CONNECTIONERRORTITLE",nil)
If you look at the last part of the first one, it says 'ITLE', not 'TITLE'
Rename the InfoPlist.strings file to Localizable.strings (double clic) and then you will get the correct string for that key.
If you wrote double semicolons at the end of a line, NSLocalization does not working.
You should check Localizable.strings file if there is ';;'
When you are developing an SDK. You need some extra operation.
1) create Localizable.strings as usual in YourLocalizeDemoSDK.
2) create the same Localizable.strings in YourLocalizeDemo.
3) find your Bundle Path of YourLocalizeDemoSDK.
Swift4:
// if you use NSLocalizeString in NSObject, you can use it like this
let value = NSLocalizedString("key", tableName: nil, bundle: Bundle(for: type(of: self)), value: "", comment: "")
Bundle(for: type(of: self)) helps you to find the bundle in YourLocalizeDemoSDK. If you use Bundle.main instead, you will get a wrong value(in fact it will be the same string with the key).
But if you want to use the String extension mentioned by dr OX. You need to do some more. The origin extension looks like this.
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
As we know, we are developing an SDK, Bundle.main will get the bundle of YourLocalizeDemo's bundle. That's not what we want. We need the bundle in YourLocalizeDemoSDK. This is a trick to find it quickly.
Run the code below in a NSObject instance in YourLocalizeDemoSDK. And you will get the URL of YourLocalizeDemoSDK.
let bundleURLOfSDK = Bundle(for: type(of: self)).bundleURL
let mainBundleURL = Bundle.main.bundleURL
Print both of the two url, you will find that we can build bundleURLofSDK base on mainBundleURL. In this case, it will be:
let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
And the String extension will be:
extension String {
var localized: String {
let bundle = Bundle(url: Bundle.main.bundleURL.appendingPathComponent("Frameworks").appendingPathComponent("YourLocalizeDemoSDK.framework")) ?? Bundle.main
return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
}
}
Hope it helps.
To find out if the Localizable.strings file is being found, check the content of your .app build and you can also do this in code:
//en is for English for example so specify yours here
NSString *path = [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
If path is NULL, it means file not found.
If you have any extra semicolon in your strings file, it doesnt localise.
I faced a similar problem, suddenly my localizable strings didn't work at all. Then I used file-compare with the old .strings copy, and at-last I found I have accidentally deleted a key in it.
So Definitely if the format is wrong Xcode will not read the strings for you.
This is the format it expects "Key" = "Value";
Because I stumbled upon this when looking for the answer to a similar problem, I'm leaving my solution here:
If your key has "\u2028" in it instead of "\n", it will always return just the key and not the value. Seems to be a bug with localization.
We were dealing with an issue in which some keys were not getting their values despite all of them existing in Localizable.strings.
Turns out that the developer who built the file added two semi-colons at one line, and that caused the parsing of this file to be quite erratic.
After I found the two semi-colons one next to the other and got rid of one of them, the app wouldn't compile anymore. At this point I was able to find some lines that didn't have semi-colons. After fixing those and the app compiled, all my strings worked fine.
So having two semi-colons in the same line caused the file to compile despite it missing semi-colons in other lines.
It looks like Apple's parser for .strings file is very primitive.
Unfortunately, the plist linter was useless in our case. To find and fix the issue, I copied and pasted the entire contents of our Localizable.strings file (which is over 2000 lines long), and started copying it back in 20 line chunks and compiling each time. It was the only way to find an issue that the linter would not catch.
Put an ; at end of the lines in the Localizable.strings files.
Resetting the simulator settings worked for me.
iOS Simulator > Reset Content and Settings...
In my case, I tried clean project and delete derived data still not work. I remove several line breaks in the strings file and then Xcode find the strings again.
None of the suggested solutions worked for me, but I did solve the issue by deleting the .app file in Products
I had the issue when one language was working properly and other language worked half of the time and other time I was getting the key, instead of localized version of that key.
Problem in my case was that after manually merging version control conflict, there was extra line of '>>>>>' left, project didn't complain (not like when you miss the semicolon, it complains) and was building properly, so every key before that '>>>>>' was being translated and every key after, not.
If more simpler solutions fails, you might have to go through every line and look for extra characters (not only '>>>>>', other extra characters too), or if you are using the version control get older, stable version of Localizable.strings file and manually go through changes and add later commits.
The first line of the localization file must contain a mapping, otherwise the SDK won't read the file.
Be sure to not put '#' in front of your key or value like so:
#"key" = #"value";
It should be just:
"key" = "value";
The '#' only goes in front of the key when accessing it:
NSWebLocalizedString(#"key", #"label for coder");
I had everything working when suddenly localization just stopped translating strings. This means the file is somehow unreadable to Xcode.
This had happened to me because I had pasted a bad character in the Localized.strings file. When I deleted the few lines with the offending character (a non unicode character? bad quote signs? Couldn't tell) everything went back to normal.
To find the offending lines I made a breakpoint, and manually translated the strings in my file in the debugger, until I hit the first one that won't translate.
Did you tried cleaning and rebuilding the project?
For xcode 9.2 removing "Localizable.strings" files from the simulators for the project using console solved it for me. Here is the commands for the lazy ones like me ;)
Do not forget to replace YOUR_APP_NAME_HERE with your project name
Shell script:
cd
cd Library/Developer/CoreSimulator/Devices/
find . -name "Localizable.strings" | grep "YOUR_APP_NAME_HERE.app" | xargs rm
If you are experiencing the problem with Unit Tests it will work in simulator ;)
Swift 4:
If you use more than one bundle such as you use it in an external framework:
var currentBundle = Bundle.main
NSLocalizedString("CONNECTIONERRORITLE", tableName: nil, bundle: currentBundle, value: "", comment: "")
I resolved it using this approach.
The localize file was created with the name main.Strings. Then, I open the main.Strings files (for each language added) and I renamed them manually with the name localize.strings and add them one by one to my project, also I deleted the main.strings.
The second thing to evaluate is: check . your file, all the keys have to end with ; and be sure all the quotes are properly opened and closed.
And you can use in swift 4 :
myButon.setTitle(NSLocalizedString("forgotpassword.key", comment: ""), for: UIControlState.normal)

Resources