How do I localize static UIApplicationShortcutItems? - ios

With the iPhone 6s, Apple has introduced a new feature called "3D Touch". App developers are able to use this technology by using it within their apps or provide so-called UIApplicationShortcutItems on the home screen which appear when you 3D Touch the corresponding app icon. I've seen quite a few people out there who wanted to know how you would be able to localize those. Here's how.

What you have to do is, if you haven't already, create a new strings file called InfoPlist.strings, then you localize this strings file to the languages you wish via the File Inspector on the right.
Now, you write down a key (for example: ADD_ITEM_SHORTCUT_TITLE or ADD_ITEM_SHORTCUT_DESCRIPTION) and the correct translation for each localized file. For example:
English file:
ADD_ITEM_SHORTCUT_TITLE = "Add";
ADD_ITEM_SHORTCUT_DESCRIPTION = "a new item";
German file:
ADD_ITEM_SHORTCUT_TITLE = "Füge hinzu";
ADD_ITEM_SHORTCUT_DESCRIPTION = "ein neues Item";
Then, go to your Info.plist and enter your key to the corresponding field. For example:
That way, you get localized UIApplicationShortcutItems. Now, they look like this:
Phone language English:
Phone language German:

Related

Sets of English Strings combined with Localization that supports UIStoryboard

I have an app that is used to track/manage livestock. It currently supports one species, Sheep. We want to begin supporting multiple different species, like Goats, and Cattle. My first thought was to create something similar to NSLocalizedString(text, comment) like SpeciesString(text, species, comment) which would take the English string and the species name and translate the Sheep term Ram to the Cattle term Bull. And internal to that, I could use NSLocalizedString() to then further translate that to the proper language so that in the future I could support multiple languages as well.
I see that I can pass a tableName to NSLocalizedString() so that it will use a different file other than Localizeable.strings and that would allow me to programmatically pull values from a Spanish language file that is focused on Cattle instead of Sheep (something like Localizeable-sheep.strings and Localizeable-cattle.strings), but that won't help me with all of the text that is in the storyboard.
I know that there is built-in support for localization with the storyboard, but the problem I'm having is that when the text comes to my code, for example in viewDidLoad, it will already have been translated to the other language, for example Spanish. I would prefer to find a way to make the text in my views already have the right Language+Species combination by the time it gets to my code. But even if I did rely on programmatically swapping out the strings to use the right Species, the English will already been changed to Spanish and I'll get Carnero instead of Ram and if I try to pass that through to my SpeciesString() it won't match my underlying data, because my underlying data is keying off of the English version of the text.
Is there a way to create a custom language? I've seen this code that is used to change the localization language on the fly, and it works for swapping between en and es, but I can't create my own fake languages like en-sheep and es-sheep.
Is there either:
a) a way to create my own custom language so that the localization system will just pick my correct Language+Species combination?
or
b) a way to tell the Storyboard which table name/filename to pull strings from? So that instead of just having a strings file for my Main.storyboard be called es.lproj/Main.strings but I could instead have
es.lproj/Main-sheep.strings and es.lproj/Main-cattle.strings?
I think my inability to get my "custom language" to work was just an accidental oversight. I created an es-sheep.lproj/Main.strings and used the other SO post to programmatically set my language to es-sheep and it didn't seem to work...
... but it turned out that I had created those directories and files, but forgotten to add them to the project. Once I manually added them to the project, it started working and I was able to use my custom localizations.

How do apps display stored notifications as localised strings?

I'm trying to localise my app, and have noticed that apps like Twitter and Facebook immediately switch the language used in previous notifications stored on the server to match the devices language. How are they doing that?
For example is someone comments on a post so that the notifications is:
John commented "hi" on your post.
It's later translated into French if my device language is set to French.
Would they store a localised string such as:
%# commented %# on your post.
And then somehow reference that string in the notification along with the variables?
There are many localisation related tools out there, one is like Phraseapp. The way these tools work are fairly simply, and the localisation is mostly front end driven, not backend.
You define a key for some content, and the key could accept parameters as well. So in your example, it could look the following.
English: user_commented_message = %# commented %# on your post.
German: user_commented_message = %# Kommentierte %# auf Ihrem Beitrag.
Than you save this into your Localizable.strings, what is being shipped with your app binary.
Once the localisation is done, all you need to do is to create the right payload for your notification. In your example, it would be looking something like the following:
{
aps = {
alert = {
"loc-args" = (
"John",
"hi"
);
"loc-key" = "user_commented_message";
};
badge = 1;
sound = default;
};
}
As you can see, you pass 2 arguments in the loc-args sections, where you pretty much define, what should be display instead of %# in your key. The order of the arguments is important, they will replace the %# in the same order, as they are in loc-args sections.
In the loc-key section, you just pretty much define what key should be used from your Localizable.strings. From this on, the Notification Center will just display the notification based on the device language settings reading the content the localisation dictionary, the Twitter or Facebook server has nothing to do with it.
For further reading, i would recommend to take a look at the Apple notification programming guide.
EDIT
This post says you are not able to use body and loc-args at the same time. It is an exclusive EITHER ONE or the OTHER relationship.
If it is in your app, than simply just use localisation. Do not send hard coded language content or store hard coded language text on the server, always use every text content with the localisation keys. It is still front end driven, the server should only keep the localised keys, not the content itself.

Suitable data structure to save localized settings

Here's the scenario. I have a set of settings in an app. For example consider my app as a video player. So there are settings like allow full screen, display subtitles etc. All these settings have boolean values since you either turn on or off them.
These settings should display inside the app in a table view. And if any of them are activated or when the user taps on them to activate/deactivate, you show it by setting the checkmark accessory view of that cell.
Since I need the settings to be displayed this way and only within the app, I cannot simply use Settings bundles. There's also another catch. I need these settings to be localized.
What I initially thought was to have separate plists for the languages I support.
Settings_en.plist (English)
Settings_sv.plist (Swedish)
Then fetch the plist name depending on the system language and display its values.
let filePath = NSBundle.mainBundle().bundlePath.stringByAppendingPathComponent(NSLocalizedString("SETTINGS_PLIST", comment: ""))
But this is not ideal because say I'm running in Swedish and I change the Subtitles setting to on. Now i have to update this in both plists. This will quickly become even messier if I add more languages in the future.
Is there a better way to store settings which is easier to save and fetch and also supports localization?
I was able to find an answer elsewhere. Here are the steps taken to resolve this issue.
Instead of multiple plists, create one plist and have the keys in English language.
Then have the localized strings in your string files with the same English keys.
Localizable.strings (English)
FULL_SCREEN = "Full Screen";
SUBTITLES = "Subtitles";
Localizable.strings (Swedish)
FULL_SCREEN = "Helskärm";
SUBTITLES = "Undertexter";
In the code when you're displaying the values in a table view, refer to them by that key.
let setting = settings[indexPath.row] as [String: Bool]
let title = setting.keys.first
cell.textLabel?.text = NSLocalizedString(title!, comment: "")

Localization: Need English Version Only

I'm having trouble reading a NSLocalizedString through my English .csv file.
In my app a user comes across a UITableViewController and selects a row. Whatever that row's title is is set to a global NSString selectedRow inside a NSObject (this NSObject is imported in every class). Once this occurs the next UIViewController reads selectedRow, runs through the .csv file until it comes across it, and then vomits all the information needed onto the UIViewController.
Example: selectedRow = "About"; so in French this would be selectedRow = "Environ";
Now I don't have "Environ" in my .csv file, I have "About", so how would I force a NSLocalizedString to be English for a few moments without having to make a completely new French version of my .csv file?
If you want to use NSLocalizedString then you would need to make .string files, if your CSV is actually static and want to translate words like "About" then you can follow the instructions here to add the .string files, make one for English, one for French, then if the user is using French as the Language Setting, they will see the content in French... If your .csv is not static and it constantly changes and has full sentences, then this probably wont work, and you would probably want to use a french version of the .csv file... You can localize it as described above too..
Hope this helps
Daniel

iOS NSString - Creating upper case based on locale

My iOS application has language selection option.
Its a server based application that receives all the strings from server that are to be displayed in the app.
In one of the view, i've to convert text to "upper case", for that I'm using NSString's upperCaseString method. This is working good for English. But for other languages like French, Chinese, Russian, German etc, it might create problem. So, I've to use "uppercaseStringWithLocale" to provider appropriate upper case string.
My question is how to create the NSLocate and pass it to "upperCaseStringWithLocale" method based on the language name. I know what's the language of the app that user has selected. Can I create locale object based on language name.?
I think you are looking for:
NSString *theLocaleIdentifier = #"es_ES_PREEURO";
[[NSLocale alloc] initWithLocaleIdentifier:theLocaleIdentifier];

Resources