Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a function macro to check key between multiple localized string files?

I have a Localizable.strings file for my project's i18n, and a lib uses KYLocalizable.strings.

I have considered to make Localizable.strings "subclass" from KYLocalizable.strings, but it cannot as far as I know. So instead, I want to define a function macro like what SDK does:

#define NSLocalizedString(key, comment) \
    [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
    [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]

Pseudo code:

#define CustomLocalizedString(key, comment) \
    // if key exists in Localizable.strings
    //   use it
    [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
    // else
    //   search it in KYLocalizable.strings
    [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:@"KYLocalizable"]

so I can just use CustomLocalizedString(<key>, <comment>) in my project.
But how to check whether the key exists in Localizable.strings or not?

Thanks in advance!!

like image 270
Kjuly Avatar asked Dec 26 '22 17:12

Kjuly


2 Answers

In this call:

[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

The value parameter (currently an empty string) will be used if a string can't be located in your strings file using the specified key. So... all you should need to do is place your second lookup to KYLocalizable.strings as the value to that parameter. The code would look similar to this (I didn't actually run this, but it should be close):

[[NSBundle mainBundle] localizedStringForKey:(key) 
    value:[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:@"KYLocalizable"]
    table:nil]

At that point, the string in Localizable.strings will be used if found. Otherwise, the value in KYLocalizable.strings will be used. If it isn't found either, then a blank string will be returned (since that is what is specified in the nested value parameter).

However, one inefficiency of this approach is that your application will actually attempt the lookup in KYLocalizable.strings first on every attempt (so that this result can subsequently be passed in as the value parameter when doing the outer lookup to Localizable.strings). If you actually want to check Localized.strings first, and then only do a second lookup if the string isn't found, I think you'd need to create a method with that logic in it (for example, add a method in a category on NSBundle).

like image 51
jolson474 Avatar answered Jan 13 '23 14:01

jolson474


If the key doesn't exist, the string you will receive will be the key itself. So as long as you suppose you will never use the key as a localized string, you can test if NSLocalizableString returned you the key or not.

like image 26
Xval Avatar answered Jan 13 '23 15:01

Xval