How to localize custom Done button - iphone

I use Done button in my custom view and I'd like to make its title localizable. I know that system Done button from UINavigationBar is already localized and it would be perfect to get it's localized strings somehow. Is there a way to do this?
Using the whole UINavigationBar only because of localized Done button seems to be inappropriate.
Clarification: the point is to use the same localized strings, that system uses.

There isn't an official way to get standard strings from the OS, but it's highly likely that all the strings will be in localized strings files, and most of those are present on the simulator (it won't have strings from apps that aren't present on the simulator, but should have almost all the strings from frameworks).
The simulator's framework directory is relative to your Xcode install directory and something like this (typing it from memory, change the version as appropriate):
Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/
To start with, I'd look in UIKit.framework/en.lproj/*.strings (or English.lproj or en_US.lproj). Strings files are plists and will generally be binary plists on device (such files start with "bplist00"). There are various ways to open these: TextWrangler will automatically display plists as XML, and the command-line tool plutil will convert to other formats. I use the bash alias
alias plist-dump='plutil -convert xml1 -o /dev/stdout --'
When you've found the string, you have a couple of options:
Load it directly from the framework at runtime with something like
[[NSBundle bundleWithIdentifier:...] localizedStringForKey:#"DONE" value:nil table:...]
This is not recommended. Yhere's no guarantee that it will work on a different OS version. (In practice, a string like "Done" probably won't move, but the alternative is easy enough that it's not worth the fuss.)
Copy the strings into your project. I don't know of a tool to automatically do this and merge with your existing Localizable.strings, but it probably exists somewhere and would not be too difficult to write. Slightly legally dubious (but not much more so than copying strings by eye for the languages you care about); I would definitely avoid doing it on a prerelease SDK to avoid concerns about Apple's NDA.
Copy the whole strings file into e.g. UIKit.strings and use something like NSLocalizedStringFromTable(#"DONE",#"UIKit",nil). Likely to be a copyright infringement!
In practice, I think Apple is unlikely to care about copying a handful of strings/images from iOS into an iOS app. Copying them into an Android app is another matter entirely...

Just add needed localization in project settings, all system stuff like done button will be localized by device locale if you added it, else it willbe on default language which you also should set up.
For custom button:
[self.myButton setTitle:NSLocalizedString(#"my localizable title", #"") forState:UIControlStateNormal];
It also valid for any NSString in your project.
NSString *someText = NSLocalizedString(#"my localizable title", #"");
self.myLabel.text = someText;
You should make your app localizable anyway by adding needed localizations.
After that just follow this instructions:
http://www.raywenderlich.com/2876/how-to-localize-an-iphone-app-tutorial
But I really recommend to you to do this in the end of project.

Related

iPhone UI internationalization

When I do translation for web apps, usually I have a script that extracts the strings from the code to a .po file that then I give to the translator, and he has a neat tool that allows him to easily translate all the strings.
On iPhone, is kind of the same thing with the Localizable.strings when it comes to strings in the .m files.
My question is: for translating the UI (the XIB files), my translator will have to have a Mac in order to edit the XIBs or is there a way to extract all the string neatly out of the XIB into a more friendly file format ?
I'm thinking on re-initializing all the XIB elements that have string in viewDidLoad but looks to me like overkill ...
I have seen ppl use ibtool. This might help you.

iphone: How do I make my app support two or more languages?

I have my app with english version. I want it to run with french text also.
What steps I need to perform? or what API or extra code I will need?
Any examples or tutorial will help me more.
You need to add localizable strings for all the languages. And also you need to add the .lproj along with the localized file for each language you want to provide the support for.
Hope this helps you.
EDIT:
I have some of these links useful for you.
http://www.icanlocalize.com/site/tutorials/iphone-applications-localization-guide/
http://adeem.me/blog/2009/05/09/tutorial-iphone-localization-in-xib-nib-files/
How simplify iPhone localization?
http://www.raywenderlich.com/2876/how-to-localize-an-iphone-app-tutorial
I feel the last one which is from http://www.raywenderlich.com is the best one I would recommend.
Hope this helps you.
Thanks
The tutorials are good for starters but you should consider following points before you start:
"normal" localization where you localize XIB files is not really recommendable when the XIB might change, since you have to maintain multiple XIB files (for each language there will be a standalone XIB) Honestly this becomes a pain after a while
Therefore I suggest (even though it is more work at the beginning) to set the labels and button titles programmatically:
mylabel.text = NSLocalizedString(#"text:", #"text:");
[mybtn setTitle: NSLocalizedString(#"textbtn", #"textbtn") forState:UIControlStateNormal];
Then use: genstrings -o en.lproj *.m to create the strings file which will look for all those NSLocalizedString and create a file Localizable.strings in the folder en.lproj
If you follow this advice it will make live easier for you in the future - though it's not really 100% comfortable yet. If you need to add a new NSLocalizedString (eg because you have a new label) you need to create a completely new file Localizable.strings. Make sure you have a backup copy of this file where you have the translation, otherwise it gets overwritten and lost. I haven't yet come accross a good solution how to build up the strings to be translated...
ps there is no need to add localized XIB files anymore.. otherwise you end up having multiple XIB files which one wants to avoid in the first place...

One App, Multiple Branding

I have made an application for the iPhone but it is required to be released with multiple brandings. Eg Differernt:
App Name
Icons
Default.png
Text replaced for the app name in IB
Colour schemes for all images such as backgrounds, icons etc
I'm not sure of the best way to do this.
I was thinking of a plist file for each branding that would have the name of the files to load eg "brand1_background.png" for brand1 but that would get very messy with the text replacement. It would also mean that all brands images would be in the package making it of larger size.
Looking around a bit I could have an 'images' folder for each brand and drag it in to build that brand's app, however the text is still an issue.
I'm wondering how everyone else would handle this situation as I want to do it as right as possible.
There are 2 different aspects to this problem, which I'd describe as follows:
Stuff that can be changed dynamically
Stuff that can't be changed dynamically
The first category is super easy. If you have your colo(u)r schemes stored in some easily-readable format like a plist or whatever, you can just load up that file during app startup, and build UIColor objects from them and use those where appropriate. The same goes for images used within the app itself. This is not a hard problem.
The second category is trickier. This is stuff that has to be baked into the application because of code signing. This means that the things like the App Name, the icon, Default.png, etc, all have to be changed before the app is signed in the compilation process. So what I'd do is bake up a bunch of scripts to take your branding information (name, image files, icons, etc) and load it up, then generate your Info.plist file and whatnot. This should be done as one of the first phases of your compilation.
For what it's worth, I work on an application where we do exactly this process, and it works pretty well. It's a bit tedious to update when we change what resources get branded, but I'm not sure there's any decent way around that.
Create a target for each of your brandings. For each single target you can add different files (e.g. images) and set an app name. You can even use the same file names (but stored under a different location) and you can build your brand-apps pretty fast.

UIBarButtonSystemItem localizable

How can I make UIBarbuttonItem localizable?
My implementation:
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(cancel)];
Originally I thought that it is automatic, because it looks easy to make it like this, but looks like not.
EDIT1: Official Apple dox says that cancel, done, edit, save buttons are localized, but not sure how to make it.
Alright, I think I know what's going on.
UIKit decides in which language to display strings, based on the value of [[NSBundle mainBundle] preferredLocalizations]. The idea behind this is to use translated resources whenever possible, falling back to English otherwise. For example, if you don't provide the translation of your app in Finnish and Finnish is selected in Settings->General->International->Language, your app will be in English. It may be a bit more complicated (UIKit may go through all the list of languages in the order displayed in Settings.app, trying to find the first language your app has translations for), but the point stands.
The above may be too obvious to miss a crucial nuance. The language determined by the above algorithm is used for the app's whole UI. For example, if the app bundle doesn't contain sk.lproj, nothing will be displayed in Slovak. In fact, it does make sense because otherwise some parts of UI would be in Slovak, other parts, in English.
Open the compiled app's bundle to see which *.lproj folders are there. The same set, sorted according to user preferences, will be returned by [[NSBundle mainBundle] preferredLocalizations]. All localizable strings, including system bar button items, will be displayed in one of those languages. If you don't support, for example, Russian, the whole UI will appear in another language, even if Russian is selected in Settings.app.
If this is the case with your app indeed, there are two right things and one wrong thing to do:
right: provide Slovak translation for each and every string displayed in your app, translate any text-containing nibs to Slovak too;
right: ignore Slovak altogether if you cannot (or don't need to) support it;
wrong: select any strings file or any nib, open Xcode's inspector, click "Add Localization…" (if the button is disabled, first click "Make File Localizable"), type "sk", click "Add" and build the project. This will make UIKit think your app is translated to Slovak, and system bar button items will automatically appear in Slovak when it's selected in Settings.app.
If you see a different behavior, there may be something wrong with the project/build/built app. For example, I noticed that when you make a file localized, its non-localized copy doesn't get deleted from the previously built app bundle.
Bump, but I think Vanya’s problem might be the “Localization native development region”/CFBundleDevelopmentRegion entry in Info.plist. If this is set to English and no localizations are explicitly made available as Costique explains, all system strings will be non-localized. But, set it to sk and - violà.
Not sure I understand your question correctly, but standard (system) bar button items are localized and thus automatically appear in the user-selected language. There are notable exceptions like UISwitch showing 0/1 instead of ON/OFF. What language are you having problems with?
That said, you can always use custom bar button items in place of system ones and provide necessary translations yourself. It's just overkill in most cases.
My implementation in Swift:
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped(button:)))
This uses the system default language for "Done" text.

iPhone Localization: simple project not working

Im doing my first localized project and I've been fighting with it for several hours with no luck.
I have to create an app that, based on the user selection, shows texts and images in different languages.
I've read most of Apple's documents on the matter but I cant make a simple example work.
This are my steps so far:
1) Create a new project.
2) Manually create a "en.lproj" directory in the projects folder.
3) Using TexEdit create file called "Localizable.strings" and store it in Unicode UTF-16. The file looks like this:
/*
Localizable.strings
Multilanguage02
Created by Gonzalo Floria on 5/6/10.
Copyright 2010 __MyCompanyName__. All rights reserved.
*/
"Hello" = "Hi";
"Goodbye" = "Bye";
4) I drag this file to the Resources Folder on XCode and it appear with the "subdir" "en" underneath it (with the dropdown triangle to the left). If I try to see it on XCode it looks all wrong, whit lots of ? symbols, but Im guessing thats because its a UTF-16 file. Right?
5) Now on my view did load I can access this strings like this:
NSString *translated;
translated = NSLocalizedString(#"Hello", #"User greetings");
NSLog(#"Translated text is %#",translated);
My problem is allowing the user to switch language. I have create an es.lproj with the Localizable.strings file (in Spanish), but I CANT access it.
I've tried this line:
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:#"es", nil] forKey:#"AppleLanguages"];
But that only works the NEXT time you load the application. Is there no way to allow the user to switch languages while running the application??
Do I have to implement my own Dictionary files and forget all about NSLocalizableString family?
Thanks for ANY advice or pointers.
Gonso
There is already a discussion about that here.
Their suggestion is to create a sub-bundle and then use a method called NSLocalizedStringFromTableInBundle(...) (as described in the reference manual) to
get a localized string from a specific table in a bundle.
I am just giving you an hunch, I haven't tried but, I guess, this could be a good way to face your problem.