Force a specific localization to be used for a target - objective-c

I'm developing an app that, among other things, will play a large audio file (30MB).
I want to submit the app to the App Store in several countries. The audio file is different per target country, the rest of the app remains the same (Although localized).
I've created a target for each country, a bash script takes care of copying the correct audio file into compiled app based on the target, and it works great.
I've also localized the ressources (Images and Localized.strings) to make it easy to maintain.
Let's say I built my target for Sweden, I want to include only the swedish localization to force the app to always show swedish language (Which matches the audio file).
Here's the actual question:* How do I exclude all localizations from a target or force a target to ONLY use a specific localization, regardless of phone settings?

Based on your comment in answer to Lvsti (where you say the reason you're doing this is that translations in some of your languages aren't finished yet but you want to release what you have), perhaps as an alternative to deleting all the relevant localization files or messing with your build settings you can try to edit the list of languages in your XCode project? It's not per target but per project, but it might allow you to exclude languages you don't want in your build. See under Localizations in your project settings (there's a little - icon you can use to remove a language).

I think you might be able to pull it of by going to:
Target Settings => Info => Add a new row called Localizations => Add a new element to that array with the kind of language you want (I think the default is english)
I haven't tested it, just let me know if it worked.

If I understand your question, you don't actually need a localized app, or at least not a fully localized one. If that is the case, I would use a run-script build phase which is responsible for copying the appropriate non-localized but target-specific resources based on the current target. E.g. supposing you have an Audio folder in your project root with all the versions for the different languages, your script could look like:
cp "$PROJECT_DIR/Audio/$TARGETNAME.mp3" "$TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/audio.mp3"
which would e.g. copy/rename "Swedish.mp3" to "audio.mp3" directly accessible from the bundle.

Related

Build multiple apps with same core

I have few separate apps that have absolute same logic and functions but have different icons and some design elements. The problem is that when some changes to logic and functions are made - I need to manually add this functionality to all apps and after this - I need to resubmit each app.
Maybe there is some way to separate all logic so I need to change it only in one place, and all my apps would get it?
In my opinion the neatest solution is to have one codebase with multiple targets. Yes you still have to resubmit each app when you change some code, but you would have to do that anyway would you not?
You can pick one of your apps to convert to your 'main' codebase.
E.g. Pick app one and duplicate the target multiple times:
You will want to change your scheme names after doing this:
You can set the bundle identifier and deployment info separately for each app just as you did before, and icon sets:
To differentiate between your apps in code you can use compiler flags (Target -> Build settings - Other swift flags) :
You can then do something like this in your code:
#if APP_ONE
...
#else
...
#endif
One solution (though not necessarily the best) is to have a single code base. I.e. you have only one physical copy of each of your classes. All your code files are located in a folder of one of the projects and the other projects use those files as well. It's just a matter of setting paths.
In this structure when you change or add some code in one of the projects (and doesn't really matter which one), all the projects are updated.
The image catalogs are different for each project.
The disadvantages of this approach are that you still need to build and submit each app separately and when adding a new class you need manually to add it to all the projects. Otherwise they won't compile.
The advantages are that when building an app, you build only one app and not all together (less time). It's also easy to manage changes to a specific app - you can just add some extension with additional functionality to only one project - the rest won't need it.

How to use get all NSLocalization using genstrings while preserved current translations

Let say my iOS app already have translation localizatible.strings for Japanese. Say "Continue" = "続ける";
However, I've added new NSLocalization additions to my code but I want to use genstrings to get all new NSLocalizations without having to merge them manually.
Is there any way to do that?
There are tools that manage localization and that automatically make updates to translations based on changes to the base language (and helping the translator make the necessary changes only to whatever has been changed).
For example www.gengo.com has a free online tool called Strings (which I haven't tried yet). There are also desktop apps that look very good, such as Localization Manager as part of Localization Suite http://www.loc-suite.org/ (which I haven't tried properly yet either).
Localization agencies may have their own tools, too.
These tools are a must if you do a lot of updates and have several languages but for smaller projects, they can take a bit too much getting used to. For an occasional task or a small project with few languages, manually merging the changes of your base language localizable.strings files to your translated localizable.strings files might be quicker though.

Is it possible to hook the API call that puts text on Mac OS?

There's a program called PPStream which is currently only available in Chinese, it allows for access to a myriad of ad-supported movies and TV series. The problems is that it is in Chinese and menus are indecipherable.
Is it possible to hook into the part of Mac OS's API that puts text on the screen so that it routes it through a wordlist first, translating the text into English? Would the API hook be able to differentiate the different applications calling the API?
I have no experience at all with Mac APIs, just pondering on if this is worth pursuing or not.
Thanks.
Edit: The reason I would like to do this at API level is that I need to dynamically dispatch HTTP queries with a list of strings to be translated (movie titles Chinese -> English), and the edit-the-i18n-file approach wouldn't do. Any other suggestions?
I haven't downloaded, installed or run PPStream myself so I'm speaking "out of my rear end" in a sense, but there are a number of ways to localize an app. But you really need to have access to the raw, uncompiled code and project to do it correctly.
The three most likely ways the string resources are saved are these:
1)
The app may have a strings file from which it fetches the strings to be displayed in the interface.
You may be able to make a copy of this strings file and set it to English or whatever language you choose.
2)
The strings may be baked into the code itself. This is generally a NO NO for commercial grade MacOS & iOS apps, but lazy and/or inexperienced developers can do this especially if they don't think their app will ever be used in other languages.
3)
The most likely set up is that there will be a folder hidden in the application package, inside the "Resources" folder, that has named like "en.lproj" or "English.lproj" or "de.lproj" or "zh_CN.lproj" or "zh_TW.lproj" (these last two are especially likely if this is only in Chinese).
Inside those folders will be localized XIB (or older NIB) files. And if you make a copy of this folder and then modify the newly made copy to add your new language.
Options 1 & 3 are ones you might be able to copy and then modify, but then again it might not work (especially these days when there's code & app signing). I've never tried this without an accompanying project, so if you have success, you should comment your question and/or this answer and let us know.

Xcode: Run project with specified localization

My Cocoa project is localized in Italian (my language) and English language.
If I run it, i see everything in Italian (of course, my OS is italian!).
How can I run it to test the English localization without changing the OS language?
In the old times, Leopard and before, the get info window in Finder would let
you choose the available languages. So it was a matter of deselecting the
language that you don't want to use and it would "default" to the other.
These days you can use an utility like this one. I'd love to know what it
does behind the scenes though.
I finally found a nice solution in the cocoa-dev mailing list archives.
Apparently, you can change the default domain within the arguments passed to
your executable, and this causes the global preference to be overwritten. It
can be achieved with the -AppleLanguages flag, pass a list of the languages
in the preferred order:
~/apath/AppName.app/Contents/MacOS/AppName -AppleLanguages "(Italian, English)"
Run this from your terminal and it should give a different precedence for the
language. Notice you can also specify a single element list "(Italian)"
—makes more sense for testing purposes.
To do it within Xcode and avoid the terminal, go to the menu Product > Edit
Scheme… . Then, in your run configuration switch to the Arguments tab and
create a new one to be passed on launch. Add -AppleLanguages "(Japanese)"
text to it. Something similar to this:
Assuming you have a file that holds all the strings, swap the names of the files. Or, if you've got a it.lproj and en.lproj group in your project, just move your InfoPlist.strings (or whatever you named it) into the other group and vice versa.

Best way to share code between multiple projects in iOS

We're planning to launch a serie of applications in AppStore. They will be for some kind of different journals, showing different contents downloaded from a server via XML. So these applications will be made from exactly the same code (It's an universal application, so It'll work both in iPhone/iPad).
My initial idea was, in order to upload the application, compile just changing the images, logos and configurations (plist) that makes the application react as a particular journal. The compressed file would be uploaded to the AppStore.
However, this has resulted a horrible method, which promotes failures and mistakes. If I forget to change some image, as you can't see them in the compiled file (as it is included) they will end up in the store (and I will need four or five days in order to get the application changed).
I'm trying to look up for a better approach, wich keep the projects as independent as possible. I would like to be able to share the entire codebase: views, classes and nibs and create different projects for every journal.
Which is the best method to achieve that?. What structure would let me group both logic (controllers, classes) and UI and use it in the different projects?.
I hope I've explained.
As always, thank you very much.
You should keep most of your common code as a library project. Each final project should link with this project and provide images/assets along with code to mention these assets to common code. In my day job, I write a common library too, which gets used by 2 products/apps at my employer.
An Xcode project can have multiple Targets, all the Targets sharing code, but each Target getting its own resources (icons, images, text, plists, etc.) from a different subdirectory/folder within the same project directory/folder. Then you can check the whole thing, or just the shared source, into your source control repository.
You should also be testing each of your apps, built exactly the same way as any submission except for the codesigning, on a device before uploading to the store.
You can have a single Xcode project that creates multiple applications. You'll need to create a separate Info.plist with a different bundle identifier for each app.
If you are using a git repository you can just branch for each different app you want and that would keep track of all the differences and if you need to switch which you are working on you just have to checkout that branch. This would allow for the exact same structure just minor differences between the actual code for each.