Making localization work - objective-c

I have an app that needs to be localized.
After fiddling with the settings for a while, I managed to get the project to the state where it builds a nl.lproj (amongst others) directory in the Resources directory of the app bundle, which contains a MainMenu.strings file that contains all my translations; they seem correct at first glance.
The XIB file is marked as translatable, and seems to be part of the right target:
However, if I run the app in a dutch environment, the localized strings are not shown in the UI. I added
NSLocale *loc = [NSLocale autoupdatingCurrentLocale];
NSString *lang = [loc languageCode];
NSLog(#"Current language: %#",lang);
to verify that the Dutch language is active, and it is.
This question suggests that doing a clean followed by a rebuild of the app should fix such issues. I've tried that, but it did not resolve the issue.
How can I figure out why my app isn't being translated? What else could go wrong? Are there any diagnostics I could be checking?
The application in question is open source, and can be found at https://github.com/Fedict/eid-mw. Select the "eID Viewer" target, and build that, to see what's happening.

There are two different things with the localization. One is localization the UI. This is done by checking those boxes and then editing the string files in the dialog underneath the xib file.
The second is the localization of the Userfacing strings in code. This is done by the Macro NSLocalizedString(#"*key*", *comment*); where key is the key and comment is a provided comment for localization purpose.
These strings are the to edit in the File Localizable.strings.
Here a link with a Beginner Tutorial. And the Apple Docs
To activate the debug function in Xcode for localized strings: pass in -NSShowNonLocalizedStrings YES as launch argument in Xcode. You find it under Product/Scheme/Edit Scheme -Arguments
Hope this helps

You need called .strings file with name "Localizable.strings".
And add language target ( in inspector ) and fill target language file.

Have you tried a check with pseudolocalozations?
Are you setting properly the language and region on your mac?
Are you also trying launching it specifically in Dutch from XCode:
To launch your app in a specific language and region
Click the target in the Run destination menu and choose Edit Scheme.
On the right, select Options.
Optionally, choose a language from the Application Language pop-up menu.
Optionally, choose a region from the Application Region pop-up menu.
Click the Close button.
Click Run to launch your app in the language and region you specified.

It turns out that localisation is supported with OSX 10.8 and above. My app had selected 10.7 as deployment target (we do need to support a few older versions of OSX). Switching the deployment target to 10.8 makes the translations appear.

Related

Open Text in App

I am looking for a way to right click selected text and open it in my app. Eg. via OS X's third party share menu. But I can not find any references at Apple's.
Have a look at the apple docs SysServices for creating a service for you app.
The Docs take you through an example of how to set one up.
Once done you will need to go into System Preferences and Enable the service. Your users will also need to do that.
Here is a quick project that shows an adaption of the apple code.
Update:
Although I think the services work good enough. Creating a Share or Action Extension is possible.
This example uses the same Project as above. But I have added an App Action extension (Target) to it.
The template for the Action is not too hard to understand and it took me 5 minutes to do this quick example.
(So I am not saying everything is as it should be but it works)
For the Action Extension:
Follow the instructions here
Which basically is:
After you choose the extension point that makes sense for your app
extension, add a new target to your containing app. The easiest way to
add an app extension target is to use an Xcode template that provides
a target preconfigured for your extension point.
To add a new target to your Xcode app project, choose File > New >
Target. In the sidebar on the left side of the new target dialog,
choose Application Extension for iOS or OS X. In the pane on the right
side of the dialog, Xcode displays the templates you can choose
Do read the above docs to understand better of what you need to do.
Once you have added the Extension. You can actually run it straight away.
Xcode provides you an option to choose a test app to test it in i.e TextEdit.app and takes you through the whole process of temporarily enabling the Extension.
In this example, remember I chose an Action Extension which suited the App.
The App's function in life is to do a basic encryption of selected text and then display the result.
The App's Action Extension will do the same but instead of displaying it, it will replace the selected text with the encryption text.
All that was needed for me to do, was copy the encryption method from the main app, over to the Extension.
I did have to adjust a couple of things though. Namely the original code deals with a NSString, where as the Extension deals with a NSAttributedString.
The conversion I did works but styling attributes are lost. For this example that does not really matter.
An Action Extension does not use the Share contextual menu. It uses an Action menu.
To see the menu, select some text and the hover the cursor over the selected text. You then should see a discloser button on the left of the text.
Like this:
Click it and choose the Extension.
If you do not see it, go to the 'more' option. This will take you to the system preferences where you can grant access to the extension.
The documentation is mainly concerned about distributing the extension and App via the App store.
But you can code sign your App and extension and do a normal archive export.
From there, all should work ok with gatekeeper.
But again refer to the Docs for a fuller understanding.
Here is a link for the code signed app and also the new Project.
Encrypto2

Force item icon refresh in Finder 10.8.2

Can anyone lead me to any useful link for forcing file icon refresh in new 10.8.2 version of Finder?
I'm working on this problem for last few days and I have tried almost any solution which can
be found on internet, but those are all old samples which are compatible with old versions of Finder and do not work on newer versions of Finder (which are rebuilt on Cocoa framework).
I tried to use few commands from apple script tool to update files in Finder ('update item with necessity'), I tried few plugins from internet (nudge, finder-Refresh...), I also tried support for communication with external Mac application through ScriptingBridge framework (although very useful) but nothing gave me a desired result.
I have noticed that NSWorkspace class contains two methods: iconForFile and setIcon:forFile,
and although I could integrate this two functions in application, iconForFile function is returning image of reduced quality, so I'm stuck in that direction also.
Any idea or suggestion will be highly appreciated.
If you need to update one Application icon, just touch the App.app folder.
Close the finder windows and issue the command:
touch /Applications/App.app
Create a visible file and delete it. This will refresh finder window.
To reset for every application under Mountain Lion, try the following in Terminal:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -seed -r
That will kill all existing objects in launch services and reseed them recursively from the standard locations (/Applications, etc).
If you have a specific application whose data you need to override existing information, you can try:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f <path>
Although I've had limited luck with the latter working in some cases, so you may end up doing the former afterwards.
Type into Terminal
killall Finder
Then
killall Dock
I had this problem too. I had a .app i wanted to change the icon of.
Structure of my .app:
...noida.app/
...noida.app/Contents/
...
...noida.app/Contents/Resources
...noida.app/Contents/Resources/myicon.icns
...noida.app/Contents/MacOS
...
...noida.app/Contents/plist.Info
Now I would change the icon in the resources folder. Then I made new files in all folders. It wouldn't work. The only place that i could make a new file tha twould update the icon was in the ...noida.app/ so i made new file at ...noida.app/junk folder and then it updated.
Very interesting.
I was just fighting with this on 10.10 (although it's been a problem for years now) and the only solution I found to force refreshing a bundles icon in the Finder was to:
Open the "Get Info Window" of the bundle you want to update and select the icon by clicking on it.
Paste another image as the icon (you could have copied this from another file or from any other location with this pasteboard data).
Press return and make sure the icon changed in the Finder.
Delete the icon by pressing the delete key.
After that the bundles icon was refreshed to the new .icns file in the bundles resource folder.

How to set target settings for different builds

In xcode 4.5 how do I select different target settings for different builds for example one target setting for debug, one target setting for release etc, so I can define different icons depending on the build etc.
You have two options, neither perfect. I'm going to focus on the concrete example of using different icons depending on your build configuration, as you suggest, though both techniques can be applied more broadly.
Redirect in your Info.plist
This is the simplest way. Specify your "Icon file" property in your target's Info.plist as e.g. "Icon-${CONFIGURATION}". Then, create two ICNS icons, "Icon-Release.icns" and "Icon-Debug.icns", and add them to your project. That's it. The downside with this approach is that both icons will be copied into your built app every time, rather than just the one it needs.
Use a "Run Script" build phase
This is a little more involved but it gives you a better result. Add a Run Script build phase to your target, with the following script:
cp "$(dirname "${PRODUCT_SETTINGS_PATH}")/Icon-${CONFIGURATION}.icns" "${SCRIPT_OUTPUT_FILE_0}"
Specify its output file as:
$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/Icon.icns
And make sure your "Icon file" property in your Info.plist is set to just "Icon".
This relies on your icons sitting in the same folder as your Info.plist within your source tree (though you can edit the script however you like to suit your project's configuration).
Note also that with this approach Xcode won't be able to see that you have the icon set correctly, so for example in the "Summary" tab of your target's settings it'll still show the question mark placeholder for the icon. You'll need to do an actual build to verify it's working.
My solution is pretty close from Wade's first point, you can also add an dynamic suffix using a user-defined settings in you project configuration.
I use this solution to dynamize the icon, the bundle display name and also the bundle identifier of my build to be able to use the version from the app store beside my development version.

How do I implement a static library from libPusher in Objective-C (Xcode 4.2)?

Please show me how I can add and implement the libPusher library to my Objective-C iOS project
This is my first post on StackOverflow
I've just started working in Objective-C iOS app development for a company that I co-founded with a couple of colleagues. Our first app needs to have the libPusher library implemented in its porject. Right now, I'm at a crossroads completing the following task of adding and implementing it on Xcode 4.2:
Simply copy libPusher-combined.a and the contents of the headers directory into your Xcode project..
Source: http://github.com/lukeredpath/libPusher/wiki/Adding-libPusher-to-your-project
What does it mean by "copy"ing those files, and where should it be copied to? Can anybody who has experience with libPusher give me specific details as a list and source code on how to execute this so I can understand it better? I would truly appreciated any help, it will get our company up and running for us getting our app functioning and ready for reviewing submission to Apple Developer staff. The link I've provided will tell you more on what I'm talking about, if I need to specify anything I'll create a new post. Thanks!
What "copy" means in this context is that you want to drag and drop the .a (library) file and the header files (all the .h files) into your new Xcode project (to be precise: the file inspector is the list of files along the left side of the workspace window).
To copy anything to an Xcode project, find it in the finder, highlight all of the files you want to copy over (or just take the folder it comes in), then drag everything over the Xcode icon in the dock.
If Xcode is full screen (lion), the icon will kind of blink, then enter Mission Control mode, you then hold the files over the correct project and drop them into the Xcode file tree.
Make sure that your application is checked as a target for those files!!
If Xcode is not full screen, just drag the files or folder into the Xcode file tree and they will be added.
To link to a static library, just navigate to the name of your project>Info>Framworks. Click the plus, then select your framework if it isn't already there.

Where to find the Objective-C Runtime and Headers?

The documentation says:
/usr/include/objc
However, on my mac there is no such folder anywhere. Or can't I just see these with Finder? If so what Tools do I need to take a lookt at them? I'm just very interested to see these headers. Just for fun.
Not sure what "documentation" you're looking at, but the header files for the system frameworks can be found under their containing frameworks at /System/Library/Frameworks. So NSObject.h resides at /System/Library/Frameworks/Foundation.framework/NSObject.h.
Edit: I just checked both my machines (Tiger and Snow Leopard), and they both have /usr/include/objc/ also. So not sure why you don't.
In Finder, press shift-cmd-G and type /usr/include/objc
Or you could go to the "Go" menu in Finder and select "Go to Folder..."
It's a hidden folder.
Do you have XCode/SDK installed? If not - register at http://developer.apple.com and get them.
The folder exists and is indeed hidden from the Finder. You can show it if you know what you're doing, but it can also lead to problems if you ever accidentally delete or move something in the /usr hierarchy. Instead, use a terminal if you want to read the headers.
You can open objc.h in XCode by jumping to the definition of id, SEL or Class (in a source file, cmd-doubleclick the name or right-click it & choose "Jump to definition"; with id, then click "typedef id").
I was having a similar issue on my Mac OS 10.8 machine, so I did a bit of digging through the Xcode files. It would appear that, for reasons I cannot entirely explain, newer versions of Xcode have these file embedded in their packages.
To find them, right click on Xcode.app and select Show Package Contents. Then navigate to the following path:
Xcode.app/Contents/Developer/Platforms
This directory should include three folders, one for Mac OS X, one for iOS, and one for the iPhone simulator. Each contains its own set of header files and resources. As an example, say I chose the Mac OS X platform. The objc headers can be found in this directory:
MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include/objc/
As to why they are here and not in /usr/include/objc, I do not know. On a similar Mac machine also running OS X 10.8, I found them in their proper locations. However, this should be a somewhat accurate method of locating them if they are not there.