【问题标题】:How to define a function macro to check key between multiple localized string files?如何定义一个函数宏来检查多个本地化字符串文件之间的键?
【发布时间】:2012-09-15 04:38:27
【问题描述】:

我的项目的 i18n 有一个 Localizable.strings 文件,一个库使用 KYLocalizable.strings。

我曾考虑将Localizable.strings 设为KYLocalizable.strings 的“子类”,但据我所知,它不能。因此,我想定义一个函数宏,就像 SDK 所做的那样:

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

伪代码:

#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"]

所以我可以在我的项目中使用CustomLocalizedString(<key>, <comment>)。
但是如何检查Localizable.strings中是否存在key呢?

提前致谢!!

【问题讨论】:

    标签: objective-c ios cocoa-touch localization macros


    【解决方案1】:

    在本次通话中:

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

    value 参数(当前为空字符串)如果使用指定键无法在您的字符串文件中找到字符串,则将使用该参数。所以...您需要做的就是将您的第二次查找放在 KYLocalizable.strings 作为该参数的值。代码看起来与此类似(我实际上并没有运行它,但它应该很接近):

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

    此时,Localizable.strings 中的字符串如果找到就会被使用。否则,将使用 KYLocalizable.strings 中的值。如果也没有找到,则会返回一个空白字符串(因为这是嵌套的 value 参数中指定的)。

    但是,这种方法的一个低效之处在于,您的应用程序实际上会在每次尝试时首先尝试在 KYLocalizable.strings 中查找(以便随后可以在执行时将此结果作为 value 参数传入Localizable.strings 的外部查找)。如果你真的想先检查 Localized.strings ,然后 only 如果找不到字符串,则进行第二次查找,我认为你需要创建一个方法在其中包含该逻辑(例如,在 NSBundle 的类别中添加一个方法)。

    【讨论】:

    • 效率低下让我很沮丧,但由于我使用这段代码的地方并不经常被解雇(它只是为了错误),它会做的。谢谢!
    【解决方案2】:

    如果密钥不存在,您将收到的字符串将是密钥本身。 因此,只要您假设您永远不会将密钥用作本地化字符串,您就可以测试 NSLocalizableString 是否返回了密钥。

    【讨论】:

      【解决方案3】:

      感谢@Xval,我自己想出了一个简单的函数(如果您有更好的想法,请提供一些建议):

      #define KYLocalizedString(key, comment) \
        [[[NSBundle mainBundle] localizedStringForKey:(key) value:nil table:nil] isEqualToString:(key)] ? \
        [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:@"KYLocalizable"] : \
        [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
      

      localizedStringForKey: 将返回一个 NSString,正如@Xval 所说。 :)

      【讨论】:

        【解决方案4】:

        对于斯威夫特:

        var key = "your_key"
        NSBundle.mainBundle().localizedStringForKey(key,
                                                     value: NSBundle.mainBundle().localizedStringForKey(key, value:"", table: nil),
                                                     table: "Your_Custom_Localizable_File")
        

        只是为了澄清一些事情,根据 Apple 的文档:

        If key is not found and value is nil or an empty string, returns key.
        

        因此,使用这种技术,您可以嵌套调用任意数量的本地化文件。

        【讨论】:

          【解决方案5】:

          我为本地化字符串编写了这个方便的扩展,因此您可以使用localized() 函数来获取本地化字符串(您也可以传递参数)和isLocalized 计算属性来检查字符串是否本地化:

          extension String {
          
              var isLocalized: Bool {
                  return localized() != self
              }
          
              func localized(parameter: CVarArg? = nil) -> String {
                  if let parameter = parameter {
                      return String(format: NSLocalizedString(self, comment: ""), parameter)
                  }
                  else {
                      return NSLocalizedString(self, comment: "")
                  }
              }
          
              func localized(parameter0: CVarArg, parameter1: CVarArg) -> String {
                  return String(format: NSLocalizedString(self, comment: ""), parameter0, parameter1)
              }
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-04-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-27
            • 1970-01-01
            相关资源
            最近更新 更多