Find All Unlocalized Strings

Requirements

We have a project which uses NSLocalizedString macro but some strings are not localized in the Localizable.strings file. What we do is to find all these strings and implement the Localizable.strings file.

Apple's Tool

As I refered here, Apple has a built-in tool but is for Appkit application. Open the scheme, and in the Arguments tab, input the following strings to Arguments Passed On Launch:

 -NSShowNonLocalizedStrings YES

Then, build and run your Cocoa application, the unlocalized string will be shown in console.
Now the good news is that with iOS8 the console can also print the unlocalized string for the iOS app. For example:

 2014-12-16 15:53:44.073 iOSUnlocalizedTest[6251:1015330] Localizable string "name" not found in strings table "Localizable" of bundle CFBundle 0x7f9fe3515b80 </Users/XXXXX/Library/Developer/CoreSimulator/Devices/F7E36A7E-14FF-4D2A-8881-A62C14CB66DE/data/Containers/Bundle/Application/18EB0513-5162-4CEC-9823-17AC3B513EFB/iOSUnlocalizedTest.app> (executable, loaded)

However, this is not the final answer as it is just a runtime checking not a static checking(As the setting above is under the Run). You can't get all expected results at a glance.

What we do

It is apparent that we have to fix it manually. Considering all the shown strings using NSLocalizedString, we can:

  1. find all strings in 'NSLocalizedString' macro
  2. check the string whether exists in the Localized.Strings

So let's start!
Open a shell, cd to the project and then run:

grep -n -h "LocalizedString" -r ./ >>../result

it will save all the lines including "LocalizedString" to the result. In the result file, it will list the file name and line number so that we can recheck it.
Then we try to get the targeted string which is the first parameter of NSLocalizedString macro:

grep -o -n "\"\w\{1,\}\"" ./result >> singleWord

it will save all the words to singleWord file.
Then we copy the content from Localizable.String to a txt file and then using the following script find.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/sh

cat $1 | while read line
do
# echo $line
    grep  $line ./japios.txt >> ./has.txt
    if [ $? == 0 ]; then
        echo $line >> ./has.txt
    else
        echo $line >> ./nothas.txt
    fi
done

run the sh file using: ./find.sh singkeWord. It will save the localized words to has.txt and the non-localized words to the nothas.txt.
Notice in the script, japios.txt should be created from the Localizable.String file as Localizable.String file is recognized as binary file and grep can't work.

Results

Using the following steps, we can find all the unlocalized one, but there are places to be imporoved:

  1. the comment code still be figured out
  2. there are the duplicated words
  3. can't figure out those which not use NSLocalizedString macro