使用NSLocalizedString的最佳实践 [英] Best practice using NSLocalizedString

查看:116
本文介绍了使用NSLocalizedString的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我(和所有其他人一样)使用 NSLocalizedString 来本地化我的应用。

I'm (like all others) using NSLocalizedStringto localize my app.

不幸的是,有几个缺点(不一定是NSLocalizedString本身的错误),包括

Unfortunately, there are several "drawbacks" (not necessarily the fault of NSLocalizedString itself), including


  • Xcode中的字符串没有自动完成。这使得工作不仅容易出错,而且还很烦人。

  • 您可能最终只是因为您不知道已经存在的等效字符串而重新定义字符串(即请输入密码vs 。首先输入密码)

  • 类似于自动完成问题,你需要记住/ copypaste注释字符串,否则 genstring 将以一个字符串结束多个评论

  • 如果您想在已经本地化一些字符串之后使用 genstring ,你必须小心不要丢失旧的本地化。

  • 相同的字符串分散在你的整个项目中。例如,您在任何地方使用 NSLocalizedString(@Abort,@取消操作),然后Code Review要求您将字符串重命名为 NSLocalizedString(@取消,@取消操作)使代码更加一致。

  • No autocompletition for strings in Xcode. This makes working not only error-prone but also tiresome.
  • You might end up redefining a string simply because you didn't know an equivalent string already existed (i.e. "Please enter password" vs. "Enter password first")
  • Similarily to the autocompletion-issue, you need to "remember"/copypaste the comment strings, or else genstring will end up with multiple comments for one string
  • If you want to use genstring after you've already localized some strings, you have to be careful to not lose your old localizations.
  • Same strings are scattered througout your whole project. For example, you used NSLocalizedString(@"Abort", @"Cancel action") everywhere, and then Code Review asks you to rename the string to NSLocalizedString(@"Cancel", @"Cancel action") to make the code more consistent.

我做了什么(以及经过一些搜索,我认为很多人这样做)是要有一个单独的 strings.h 文件,其中我 #define 所有本地化代码。例如

What I do (and after some searches on SO I figured many people do this) is to have a seperate strings.h file where I #define all the localize-code. For example

// In strings.h
#define NSLS_COMMON_CANCEL NSLocalizedString(@"Cancel", nil)
// Somewhere else
NSLog(@"%@", NSLS_COMMON_CANCEL);

这实质上提供了代码完成,一个更改变量名称的地方(所以不再需要genstring ),以及自动重构的唯一关键字。但是,这需要花费大量的 #define 语句,而这些语句本身并不具有结构性(例如LocString.Common.Cancel或类似的东西)。

This essentially provides code-completion, a single place to change variable names (so no need for genstring anymore), and an unique keyword to auto-refactor. However, this comes at the cost of ending up with a whole bunch of #define statements that are not inherently structured (i.e. like LocString.Common.Cancel or something like that).

所以,虽然这样做有点好,但我想知道你们是如何在你的项目中做到的。是否有其他方法可以简化NSLocalizedString的使用?甚至可能有一个封装它的框架?

So, while this works somewhat fine, I was wondering how you guys do it in your projects. Are there other approaches to simplify the use of NSLocalizedString? Is there maybe even a framework that encapsulates it?

推荐答案

NSLocalizedString 有一些限制,但它是Cocoa的核心,编写自定义代码来处理本地化是不合理的,这意味着你将不得不使用它。也就是说,一个小工具可以提供帮助,以下是我的工作方式:

NSLocalizedString has a few limitations, but it is so central to Cocoa that it's unreasonable to write custom code to handle localization, meaning you will have to use it. That said, a little tooling can help, here is how I proceed:

genstrings 覆盖您的字符串文件,丢弃所有以前的翻译。
我写了 update_strings.py 来解析旧的字符串文件,运行 genstrings 并填写空白,这样您就不必手动恢复现有的翻译。
脚本尝试尽可能地匹配现有的字符串文件,以避免在更新时出现过大的差异。

genstrings overwrites your string files, discarding all your previous translations. I wrote update_strings.py to parse the old strings file, run genstrings and fill in the blanks so that you don't have to manually restore your existing translations. The script tries to match the existing string files as closely as possible to avoid having too big a diff when updating them.

如果您使用 NSLocalizedString 广告:

NSLocalizedString(@"Cancel or continue?", @"Cancel notice message when a download takes too long to proceed");

您可能最终在代码的另一部分中定义相同的字符串,这可能会相同英语术语在不同的上下文中可能有不同的含义(确定取消会浮现在脑海中)。
这就是为什么我总是使用带有模块特定前缀的无意义的全大写字符串,以及非常精确的描述:

You may end up defining the same string in another part of your code, which may conflict as the same english term may have different meaning in different contexts (OK and Cancel come to mind). That is why I always use a meaningless all-caps string with a module-specific prefix, and a very precise description:

NSLocalizedString(@"DOWNLOAD_CANCEL_OR_CONTINUE", @"Cancel notice window title when a download takes too long to proceed");



在不同的地方使用相同的字符串



如果多次使用相同的字符串,则可以像使用宏一样使用宏,也可以将其作为实例变量缓存在视图控制器或数据源中。
通过这种方式,您不必重复可能变得过时的描述,并且在同一本地化的实例之间变得不一致,这总是令人困惑。
由于实例变量是符号,您可以对这些最常见的翻译使用自动完成,并对特定的翻译使用手动字符串,这只会发生一次。

Using the same string in different places

If you use the same string multiple times, you can either use a macro as you did, or cache it as an instance variable in your view controller or your data source. This way you won't have to repeat the description which may get stale and get inconsistent among instances of the same localization, which is always confusing. As instance variables are symbols, you will be able to use auto-completion on these most common translations, and use "manual" strings for the specific ones, which would only occur once anyway.

我希望通过这些提示你可以提高Cocoa本地化效率!

I hope you'll be more productive with Cocoa localization with these tips!

这篇关于使用NSLocalizedString的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆