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

查看:20
本文介绍了使用 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 中的字符串没有自动完成功能.这使得工作不仅容易出错,而且令人厌烦.
  • 您最终可能只是因为不知道已经存在等效字符串而重新定义了一个字符串(即请输入密码"与先输入密码")
  • 与自动补全问题类似,您需要记住"/复制粘贴注释字符串,否则 genstring 将结束一个字符串的多个注释
  • 如果您想在已经本地化一些字符串之后使用 genstring,您必须小心不要丢失旧的本地化.
  • 相同的字符串散布在您的整个项目中.例如,您在任何地方都使用了 NSLocalizedString(@"Abort", @"Cancel action"),然后 Code Review 要求您将字符串重命名为 NSLocalizedString(@"Cancel", @"Cancel action") 让代码更加一致.
  • 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.

我所做的(在对 SO 进行一些搜索后,我发现很多人都这样做)是有一个单独的 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 作为宣传:

If you use NSLocalizedString as advertised:

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

您最终可能会在代码的另一部分定义相同的字符串,这可能会发生冲突,因为相同的英文术语在不同的上下文中可能具有不同的含义(OKCancel 想到).这就是为什么我总是使用一个无意义的全大写字符串和一个特定于模块的前缀和一个非常精确的描述:

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天全站免登陆