Our DNA is written in Swift

Linguan Available, Users in Ecstasy

When I first formed the idea that evolved into Linguan it was because it was a tedious process to edit strings files with text editors and never being sure if you translated everything. In school my Latin teacher told us (incorrectly) that Ecstacy comes from ex (“out of”) and tease (“cause pain”) and that is what Ecstasy really means: to be without pain.

Many years later I was reminded of that because it was a pain (you know where) to deal with translations, especially if you had more than one extra language or had to deal with translators. As soon as you update your app with some new features you instantly lose track what additional tokens which of the translators has to provide a translation for.

Linguan comes to the rescue for all of us pained developers. It’s basically a very smart editor for .strings files. Plus a validator that is able to find inconsistencies and for example if you saved a strings file as UTF8. Plus an export and merge function that lets you send all untranslated tokens of specific languages to translators and merge their results back into your project. And you can even tell your translator to get Linguan because it gives him a nice interface to work through the strings files you send him.

Linguan was my first app on the Mac app store and it was created under a partnership with BytePoets. The reason for this was that I am harboring the notion that more can achieved through partnerships than just by yourself. And the result speaks for itself.

The first user to voice his ecstasy was Joe Carney who has localization for 41 languages in one app he is working on. You can imagine his surprise about all the missing translations that Linguan informed him about.

Linguan validates your project and tells you about:

  • if a file is UTF8 instead of UTF16. iOS ignores UTF8 strings files and might cause a bad surprise if you find that your translations don’t show up.
  • if a token is translated several times. In this case it is not clear which translation is actually being used by the app.
  • if a token is not translated, i.e. missing a translation. Here iOS will fall back to using the token name itself, which might be “LOGIN_EMAIL” and look quite weird on a button.

Contrary to what I initially believed the comment you put in front of a token is not used as a primary key. So if you have the same token under two different comments then these are still the same.

I have seen two ways to use comments in projects and Linguan supports both. First you can use comments to tell the translator about the context that this string is used in because sometimes that might cause him to translate it differently. For this scenario all the comments would be different and verbose. The second method that I personally prefer is to group multiple tokens (e.g. from one view controller) under one comment. Linguan is able to show you either all tokens or group them by comment. The latter option obviously only makes sense if you use the second modus operandi.

For short texts you probably want to use the table grid view for translating. But there is also a Wizard mode that has bigger boxes if you have longer texts or multiple lines of text.

Linguan is designed to work for the developer as well as the translator. As such you have two modes, one is to open an xcodeproj which will parse the project file and show you a tree of your strings files. The other is to open a single strings file. We want you to recommend to your translators to use Linguan as well because then they won’t mess up the file structure of text file and you can easily merge in their changes.

This is where Linguan is truly amazing. It adds meta-information to the strings file that lets it know from which source file certain tokens originated from. So you could have multiple strings files in your project and have your Spanish translator deal with these in one go. Then when you merge that back into your project all new translations are put where they belong.

If you want to add new languages then you have to do that in Xcode before going into Linguan. The reason for this is that we parse the project file, but we don’t dare to modify it yet. A new localization means that Xcode adds a new lproj folder and copies all localized files into that. For the initial release version we decided against such risky endeavors.

Bear in mind that this is version 1.0. So it is possible that you find something that’s not working as expected or that you can think of features that would be nice to have. Hey “real artists ship” and so we did.

We believe that Linguan provides a piece of functionality that should have been provided by Apple, but wasn’t. So we tried to make a tool thats worthy of being mentioned with Xcode on the same breath. Check it out on the Mac App Store. If you find any issues or have feature requests then you can use our bug tracker for that.

Categories: Tools


  1. Would be reeeeally great (= perfect!) if it would support .xib-files too 🙂

  2. Wow, this is amazing. I will most certainly use it for one of my next projects. Thanks!

    I have a remark on the pricing though: 3.99€ is very much okay for us freelance developers or software companies. If I need it, I would buy it even at 20€ because it’s probably worth it considered the time saved. However for the translators, who are often volunteer users or friends, it’s probably too much. They’re already giving their time free, I won’t make them pay some software, no matter how great it is. How about making a free version that only features the translation wizard for one strings file?

    BTW, I’m volunteering to do the French translation of the app if you’d like 😉



  3. These are great suggestions!

    BUT, I don’t think that I want to get into the game of multiple editions of what is essentially a simple and focussed app. I want the price point to be at “Instant Buy!” i.e. You see the value, you see the price and decide that you get so much for so little money that you instantly push the purchase button.

    You are free to gift Linguan to all your volunteers! That’s win-win-win. 🙂

  4. This is very useful app. Recently I had to put 11 languages and it was a challenge. I created a spreadsheet that looks similar to what you see in Linguan and then copy-pasted to strings files.

    So far I haven’t had a major changes in my app, but if I had, I can imagine nightmare keeping track of the changes.

    What would be good in Linguan:
    1. If it would be possible to work with translations like in spreadsheet where you can select multiple cells, move them, etc. Especially, to move from spreadsheet, or past from plain text file where every new line would be new row (this is what you usually get from translators)

    2. If it could support refactoring source code by changing names or comments in Linguan. But this is not very critical.

  5. Just added my 4-star review in the italian Mac App Store. Really useful app, it’s a must have tool for multi-language apps. Just today I have tested it with my 15-language guitar tuner and I found many translations still missing! this software is worth the ~ 4 Eur it costs, congratulations for the idea and the implementation, in pure MacOSX style…
    The missing star in review is only to push you to add support for comments. I use them often to provide hints to the translator (e.g.: “this is the message for the alert that explains to the user he cannot proceed further”, and typically the “tone” of the translation may change between languages; as the translator often cannot see the final app, you must explain him/her the meaning of the texts). So parsing comments (typically placed as // at the end of the line) and then giving the possibility to edit them and rewrite is welcome. Comments are normally provided in one language, and this is the main app language, so I don’t need multiple language management for comments too.
    Finally another great addition (but it’s beyond 5 stars…) would be to provide support with external services that you can use to have automatic or human translations. But I know it would be difficult to implement so I will just suggest it for version 4.0…

  6. When I pressed “Scan Sources” in my project, I got this error:

    Error importing new tokens, file “AsyncSocket.strings” not found in project

    What does that mean? I’m only using AsyncSocket.h & .m, why would Linguan need AsyncSocket.strings file?

  7. Linguan scans all source files in your project. If a string macro requires a table, then a file table.strings must exist for each language.

  8. I do have a “Localizable.strings” table in the project.
    The question is, why is Linguan asking for a different strings table?

    Project setup: AsyncSocket is added as a git submodule, and the source files are dragged into Xcode without copying.

  9. because you have a NSLocalizedStringFromTable macro in the code. This needs its own strings file.

  10. I checked the AsyncSocket code and it is using this NSLocalizedStringWithDefaultValue(NSString *key, NSString *tableName, NSBundle *bundle, NSString *value, NSString *comment).

    You can see that the second parameter uses AsyncSocket as tableName. So you need an AsyncSocket.strings file if you are localizing your app.

  11. Thanks! That’s exactly the problem.
    Any way to have Linguan skip external libraries when scanning source code?

    Libraries such as AsyncSocket is not part of the UI and usually there’s no need to localize them.

  12. Alternatively, instead of an error, how about a warning?
    Otherwise, the “Scan” button is totally not working because of the error and I have to manually use genstrings.

  13. We have several feature requests in the pipeline that cover that. Sorry for the inconvenience. The quicker our user base grows the sooner we can implement these. So please help us out by spreading the word about Linguan and leaving a review on iTunes.