Localized storyboard is ignored (?) - cocoa-touch

I created a Swedish localization of my storyboard, but it doesn't get loaded for iOS devices with the language set to Swedish - it's always the English version.
I have Localizable.strings in sv.lproj, and those do work when using the NSLocalizedString macro.
Are there some additional steps required? All I did was click the plus sign under the "Localization" section.

There are no additional steps required except that when you get be ready to start working on localization (i. e. the storyboard is ready on your main application language), you should add localization to your project
and localize Storyboard for each language

Related

Localising English (whilst also developing in English) using XCode6

My app (OS X and iOS) is developed in English. I just added a German localisation and everything works well. However, I have now added a call similar to the following
NSLocalizedString(#"run1", #"Run as in 'to run'")
NSLocalizedString(#"run2", #"Run as in 'run it'")
...so I have 2 different variants of 'run'. However, there is no option in XCode6 to 'Export for Localisation (English)' since that's the base language. So how do I get run1 and run2 localised into English? (i.e. run)
I know I can do it by manually creating the .strings file in the en folder - but I was hoping to stick with the xliff workflow.
Thanks

Xcode 6 does not localize Interface Builder

Xcode 6 Beta 4 using Swift.
I use localization in my project and I have experience in localization from Xcode 5.
Localization in program code using NSLocalizedString() works fine.
Localization of Info.plist strings work fine, too.
When it comes to localize the strings from Interface Builder it only works in Interface Builder preview but not in simulator and not on my device (iPhone 5S).
Am I missing something or can anyone confirm this as a bug in in Xcode 6 Beta 4?
It seems like the problem is with the size classes.
If "Use Size Classes" checkbox is enabled for storyboard, the Xcode actually generates 3 versions of it ("<Name>.storyboard", "<Name>~ipad.storyboard" and "<Name>~iphone.storyboard").
So iOS just tries to load .strings file which name matches the name of active storyboard (<Name>~iphone.strings in case app is running on the iPhone). And being not able to find that file, it falls back to Base localization.
There are a couple of ways to work around this bug:
The most obvious one. Just disable size classes for the storyboard.
If you need size classes, you can add localized <Name>~iphone.strings and <Name>~ipad.strings files to the project manualy and copy your translations over.
Apple release notes of XCode 6 GM covers this :
Localization:
A storyboard or XIB will not localize correctly if all of the following three conditions are true:
The storyboard or XIB uses size classes.
The base localization and the build target are set to Universal.
The build targets iOS 7.0.

Launch screens supporting iOS6 and iOS7 - forced to splash screen

When it comes to the launch screen I can't find a unifying way to mimic the look of the application on both iOS6 and iOS7 (supporting both). Are we forced to make a regular splash screen of a logo or similar if we have a toolbar menu or do you guys have any great ideas how to solve it?
Short answer
In iOS 7, an app can use a different launch image depending on which version of iOS it’s running in. To provide different launch images, add the UILaunchImages key to the Info.plist file and use a dictionary to describe each launch image.
Background
It uses the following keys:
UILaunchImageName - A string containing the name of the PNG image file. The image file must reside at the top level of the app bundle.
The name you specify for this key should not include a filename
extension, nor should it include modifiers such as #2x, -568h,
~iphone, or ~ipad.
On disk, your image filenames may still include the #2x, -568h,
~iphone, or ~ipad modifiers as appropriate, although they are not
required. The system automatically accounts for such modifiers when
choosing which file to load.
UILaunchImageMinimumOSVersion - for iOS7 this should be a string “7.0”.
UILaunchImageOrientation – String containing one of: Portrait, PortraitUpsideDown, Landscape, LandscapeLeft, LandscapeRight.
UILaunchImageSize – String specifying width and height, ex: “{320, 480}”. You must specify the width and height with respect to
the device in a portrait orientation. In other words, portrait and
landscape images targeting the same device would have the same width
and height.
If this key is present, iOS 7 uses it exclusively to obtain launch
images.
BUT: I found that sticking to the naming convention also for iOS7 helped a lot!
This key is supported in iOS 7.0 and later.
OK – so now what?
Because I already had launch images for iOS6 and with all their specific naming conventions. I chose to make a copy of all of them and prefix the name with ”iOS7-” so as to limit my own confusion about all the different sizes and names. Making a prefix should prove to come in handy as then most of the images would immediately be loaded correctly.
The filenames:
I had these for iOS6 already, I also list the file sizes for those in need:
Default.png (320x480)
Default#2x.png (640x960)
Default#2x~ipad.png (2048x1496)
Default~ipad.png (768x1004)
Default1024x768.png (1024x768)
Default1024x768#2x.png (2048x1536)
Default-568h#2x.png (640x1136)
Default768x1024.png (768x1024)
Default768x1024#2x.png (1536x2048)
Default-Landscape~ipad.png (1024x748)
Default-Portrait#2x~ipad.png (1536x2048)
So I made a copy of all of these filenames for iOS7 (same sizes) prefixing them with "iOS7-":
iOS7-Default.png
iOS7-Default#2x.png
...
In XCode
Now to create your entry in PLIST. Go to your-name-of-application.plist. In a blank area, right-click and choose ”Add Row”. Make sure it becomes a top item and not a sub-item of some other information in the .plist.
Write:
UILaunchImages
Right-click on this UILaunchImages and select value type ”Array”.
Use the illustration below as a guide to the text and for how it will look when it is all finished:
If you open up this array so the little indicator triangle to the left points down, it is empty the first time, but if you choose ”add row” while it is open it will create a sub-line. Do that now:
Right-click on the UILaunchImages and select ”Add row”.
Right-click on this new line (item 0) and select value type ”Dict”
Continue opening this items with the triangle indicator and right-click and ”Add row”
This item you will name UILaunchImageMinimumOSVersion and set value type to “string” and the string to “7.0”
Now the following are all strings and should be at the same level as the UILaunchImageMinimumOSVersion item. In the same dict (dictionary). Create these by just choosing “Add row” for each:
UILaunchImageName – base-name-of-iOS7-launch-image. In my case this was ”iOS7-Default”
UILaunchImageOrientation - example: Portrait
UILaunchImageSize - the size of the elementary base iOS7-Default.png: "{320, 480}". The program will find all the files with permutations of the base name. Remember to select the base name of the file without ipad/iphone/portrait/landscape or .png specifications.
Note:
Xcode had already made the following items in the .plist for me after first adding iOS6 images in all available slots :-)
UILaunchImageFile~ipad … = ”Default” – so this was OK
UILaunchImages~ipad … Had two items that needed to be updated to iOS7 versions, because they where now incorrectly holding the iOS6 version. Those I had named Default1024x768 and Default768x1024 and now I just prefixed ”iOS7-” to each of the names and I was done.
Example of how it may look for those wanting to edit plist directly:
<key>UILaunchImages</key>
<array>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>iOS7-Default </string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{320, 480}</string>
</dict>
</array>
[edit by jd: fixed spelling of "UILaunchImages"]
Highlight the project in the project browser, select "General", scroll down to "App Icons", click on "Use Asset Catalog", and select "Migrate". Your existing icons and splash screens will be automagically migrated into an asset catalog. You can then select the catalog to add further images.
To add new images you simply drag from Finder and drop into the squares for each image type.
(Caution: The catalog editor inexplicably uses a non-scrollable wide format, and you can be missing stuff off the right side if your screen isn't wide enough.)
You can also use the new image catalogue feature in Xcode 5 to manage multiple versions of launch images.
Now you can directly add the app icons and splash images in the images.xcassets,
Click on + button to add the respective image set for iphone5 with iOS 5,6,7 ,iphone4, iPad.
now no need to set the images name like default.png,default#2x.png
Be warned when using an images.xcassets repository it will not allow you to localize your splash screens.
I'm currently trying to get a French and English version of our app.
WWW> Will this 'plist' method work if you need to localize your splash screens?
I also had the same issue with an older app that I developed for iOS 7. It Archived and Uploaded fine with Xcode 6, but the "binary not optimized for iPhone5" error returned with Xcode 7. After trying a myriad of other solutions, I was only successful by removing all references to any Launch Image (since I was using a universal .xib) AND setting the deployment target from 7.0 to 8.0

Multi language localization storyboard support issue

I have an issue with my project storyboard. I have added two localizations more to storyboard, so now I have three storyboards: spanish, english and basque. All of them depending from the main one:
Now I have the issue that I have to update all changes manually to all to storyboards, because if I do changes to MainStoryboard, the others are not updated with this changes.
How can I modify all storyboards at the same time?
Thanks
Here is a really great tutorial for automating changes from one storyboard localization to all the others:
http://danielsaidi.wordpress.com/2012/08/20/localization-in-ios/
http://www.youtube.com/watch?v=cF1Rf02QvZQ
From what I gather, the solution involves adding a python script to the end of the build that syncs the storyboards and generates string files.
Go to the links for a more detailed solution. They said it better than I can.
You could either take out all the strings from Storyboard and put them in localized set of strings. Then you would have to do everything in your code like this:
self.label = NSLocalizedString("LABEL_STRING", nil);
or you could open the Storyboard as an XML file and do it there maybe a little faster. But other than that, no it is not doable, bcs the Storyboard localization serves you for polishing your localization. Say you have a screen called "HOME" and then (using google translate), you have "HASIERA" in basque. The problem here is, that in basque it's longer, so you need to adjust the GUI elements so it fits the screen perfectly. What could happen is that the string would be cut off, which we don't want to happen. That's why you need to do Storyboard localization step by step. If you don't need it, use strings file instead...

Localizing the Cut|Copy|Paste menu on iOS

Im having some issues localizing a danish app ive made. (The language, not the pastry)
I have set the CFBundleDevelopmentRegion to da_DK for danish in my info.plist, but the popup appearing for text input is still in english, even on phones running the danish OS.
How in Jobs name can i change this ?
The test device is a non-jailbroken iPhone 4S running iOS 5.1 with Danish as its iOS setting, and a danish itunes account associated.
I do not use .xibs for designs. all interfaces are programmed as viewcontrollers.
In the Xcode's file tree (Project Navigator) select your project. in the right hand pane select your project again. select Info and add your language.
I created a sample project, this is the result:
You can do this directly in the info.plist. Something like this:
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>de</string>
<string>es</string>
<string>ja</string>
</array>
Try adding/setting the "Localized resources can be mixed" flag in Info.plist to YES.
You must localize your app in Danish to make the standard UI elements appear in that language. This is to avoid having a UI with mixed languages.
If you don't use xibs, you'd usually do this by adding a Localizable.strings file to your project. In Xcode's "Add File" dialog, you can use the "Strings File" template (under "Resources") for this.
To actually localize the strings file, open the file inspector (⌘ ⌥ 1) and click the + button in the "Localization" section. You'll end up with the file being displayed as a group in the project navigator, with a sub-entry for each language.
The strings file has the format:
"Label_Text" = "Smørrebrød";
(don't forget the semicolon)
To use localized strings in your code, you can use the NSLocalizedString macro like this:
myLabel.text = NSLocalizedString(#"Label_Text", nil);
(The second parameter is for a comment. This can be useful if you use the genstrings tool to extract localizable strings from your code and give the resulting file to a professional translator.)
If you use the English strings as keys, you can leave the English version of Localizable.strings empty (but don't delete it).
Having a Localizable.strings file in the language that the user has selected will also cause standard UI elements, such as the editing menu, photo picker, and so forth, to appear in that language.
If you can't get it working the official way, as provided by #vikingosegundo, you can do this with some creative engineering (Creative as in, oh my god that is dangerous). I discovered this method when I accidentally overrode [NSBundle localizedStringForKey:value:tableName:].
1) Add a category to NSBundle with the following methods:
#import <objc/runtime.h>
+ (void) load {
Method original, swizzled;
original = class_getInstanceMethod(self, #selector(localizedStringForKey:value:table:));
swizzled = class_getInstanceMethod(self, #selector(swizzled_localizedStringForKey:value:table:));
method_exchangeImplementations(original, swizzled);
}
- (NSString*) swizzled_localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
NSLog(#"Key: %#. Value: %#", key, value);
return [self swizzled_localizedStringForKey: key value:value table:tableName];
}
2) Where I simply log the key/value, you want to put an if ([key isEqualToString: xxx] ) block. In there, you want to catch (at least some of) the following key values: Cut, Copy[Menu], Select, Select All, Paste, Delete[Menu], Replace..., Define, Speak, Pause. These are the default values that can appear there.
3) When you have caught the value you can look up in a custom table or use hardcoded values. If you look up in a custom table make sure you have a catch in your swizzled method to avoid infinite looping in your custom table.
NB: Why do you need to swizzle? Because this over-rides all Apple text for you app. You will still want the defaults for all the other strings, so you need to swizzle to get the defaults for the strings you aren't interested in.
Good luck.
Paul
Search if your .xib is localized (you'll find it in the inspector on the right panel) if so go to your Project/Target-Settings press the +-Sign and select "Duplicate English to Danish" or something which means the same (I can't check the right item at the moment)
Btw it's called iPhone 4S.