自定义 NSLocalizedString?

发布于 2024-11-19 01:46:51 字数 178 浏览 2 评论 0原文

是否可以将 NSLocalizedString 基础结构(基于 localized.strings)与自定义定义的“本地化”一起使用?

问题是,有些语言对男性和女性有不同的措辞。我想在首次启动时询问用户的性别,然后使用适当的短语。当然,两者都基于相同的语言。我可以用自己的代码来完成,但如果可能的话,我宁愿用简单的方法来完成。

Is it possible to use the NSLocalizedString infrastructure (based on localizable.strings) with a custom-defined "localization"?

The thing is, there are some languages that have different wordings for males and females. I want to ask the user's gender on first launch and then use the appropriate phrases. Of course, both are based on the same language. I can do it with my own code but I'd rather do it the easy way if possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

月光色 2024-11-26 01:46:52

在 Xcode Project Navigator 中,

  1. 单击 Project name(列表中的第一项),
  2. 然后在打开的选项卡中单击 PROJECT 标签下的项目
  3. 选择 Build Settings
  4. 在右上角的搜索中输入 LOCALIZED_STRING_MACRO_NAMES
  5. 将自定义函数名称添加到显示的设置(除以现有设置中的空格) )
    示例: NSLocalizedString CFLocalizedString NSBundleLocalizedString
    输入图片此处描述

此后,Xcode 中的“导出本地化”选项将生成一个 XLIFF 文件,其中包含自定义函数中提到的可翻译字符串。

In the Xcode Project Navigator,

  1. click Project name (first item on list),
  2. then in opened tab click your project under PROJECT label
  3. Select Build Settings
  4. In Search in right corner enter LOCALIZED_STRING_MACRO_NAMES
  5. Add your custom function name to showed setting (divide by space from existing)
    Example: NSLocalizedString CFLocalizedString NSBundleLocalizedString
    enter image description here

After this, option "export for localization" from Xcode will produce an XLIFF file that contains translatable strings mentioned in your custom function.

三人与歌 2024-11-26 01:46:52

为此有一个特殊的机制。
来自Apple参考:使用 genstring 搜索自定义函数

genstrings 工具搜索 Core Foundation 和 Foundation
默认情况下为字符串宏。它使用这些宏中的信息来
在项目的字符串文件中创建字符串条目。你可以
还指示 genstrings 在中查找自定义字符串加载函数
除了标准宏之外,您的代码并使用这些函数。
您可以使用自定义函数来包装内置的字符串加载
例程并执行一些额外的处理,或者您可以替换
使用您自己的自定义模型的默认字符串处理行为。

如果您想将 genstring 与您自己的自定义函数一起使用,您的
函数必须使用所使用的命名和格式约定
基础宏。您的函数的参数必须匹配
对应宏的参数准确。当你调用
genstrings,您指定 -s 选项,后跟该名称
对应于 NSLocalizedString 宏的函数。你的另一个
然后函数名称应该从这个基本名称构建。例如,如果
您指定了函数名称 MyStringFunction,您的其他函数
名称应该是MyStringFunctionFromTable
MyStringFunctionFromTableInBundle,以及
MyStringFunctionWithDefaultValuegenstrings 工具会查找这些
函数并使用它们构建相应的字符串文件。

要实现您自己的行为,请使用 NSBundle 方法 localizedStringForKey:value:table:

There is a special mechanism for this.
From Apple reference: Searching for Custom Functions With genstrings

The genstrings tool searches for the Core Foundation and Foundation
string macros by default. It uses the information in these macros to
create the string entries in your project’s strings files. You can
also direct genstrings to look for custom string-loading functions in
your code and use those functions in addition to the standard macros.
You might use custom functions to wrap the built-in string-loading
routines and perform some extra processing or you might replace the
default string handling behavior with your own custom model.

If you want to use genstrings with your own custom functions, your
functions must use the naming and formatting conventions used by the
Foundation macros. The parameters for your functions must match the
parameters for the corresponding macros exactly. When you invoke
genstrings, you specify the -s option followed by the name of the
function that corresponds to the NSLocalizedString macro. Your other
function names should then build from this base name. For example, if
you specified the function name MyStringFunction, your other function
names should be MyStringFunctionFromTable,
MyStringFunctionFromTableInBundle, and
MyStringFunctionWithDefaultValue. The genstrings tool looks for these
functions and uses them to build the corresponding strings files.

To implement your own behaviour use NSBundle method localizedStringForKey:value:table:

梦一生花开无言 2024-11-26 01:46:52

这是我的自定义实现,它使用 NSLocalizedString 并使用注释作为默认值:

-->这里我转换为 2 种语言(英语和意大利语)

-->将此方法放在appdelegate类中

- (NSString*)languageSelectedStringForKey:(NSString*) key {        

    NSString *path = nil;
    NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppLanguage"];

    if ([language isEqualToString:@"English"])
        path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
    else if ([language isEqualToString:@"Italian"])
        path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];

    NSBundle* languageBundle = [NSBundle bundleWithPath:path];
    NSString* str=[languageBundle localizedStringForKey:key value:@"" table:nil];
    return str;
}

--> 来调用此方法。

 self.title = [appDelgate languageSelectedStringForKey:@"Back"];

通过转换回所选语言

Here is my Custom implementation that use NSLocalizedString that use comment as default value:

--> Here I convert in 2 Language (English and Italian)

--> Put this method in appdelegate class

- (NSString*)languageSelectedStringForKey:(NSString*) key {        

    NSString *path = nil;
    NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppLanguage"];

    if ([language isEqualToString:@"English"])
        path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
    else if ([language isEqualToString:@"Italian"])
        path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];

    NSBundle* languageBundle = [NSBundle bundleWithPath:path];
    NSString* str=[languageBundle localizedStringForKey:key value:@"" table:nil];
    return str;
}

--> call this method by

 self.title = [appDelgate languageSelectedStringForKey:@"Back"];

that convert Back in selected language.

淡淡離愁欲言轉身 2024-11-26 01:46:52

@Guillaume 提供了最好的解决方案,但没有实际展示实现。由于问题的作者无法弄清楚,我决定将其包含在未来的人们中。我发现该线程很有帮助,现在它不仅仅是有帮助。 :)

正如@Guillaume 所提到的,最好的解决方案是创建一个在表上查找的自定义宏。 “表”只是包含变体的其他文件的名称。在这种情况下,我假设您将文件命名为“Female.strings”,

这确保了最大的灵活性,并为您提供了一个不需要您为这两种情况定义条目的解决方案。这实际上对您的情况非常有用,因为并非所有短语都可能具有女性形式。

因此,以下解决方案不需要重复的条目,这非常酷!

首先定义宏:

#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]

然后定义扩展函数,如下所示:

+ (NSString*)SXLocalizedString:(NSString*)str with:(NSString*)comment {
    NSString* feminine = NSLocalizedStringFromTable(str, @"Female", comment);
    NSString* value = NSLocalizedString(str, comment);
    if ([self userIsFemale] &&
        feminine) {
        // choose the feminine version of the string
        value = feminine;
    }
    return value;
}

@Guillaume provides the best solution, without actually showing the implementation. Since the author of the question wasn't able to figure it out, I decided to include it for future people. I found the thread helpful, now it is more than helpful. :)

As mentioned by @Guillaume, the best solution is to create a custom macro with a lookup on the table . The 'table' is just the name of the other file that contains the variants. In this case, I am assuming you will name your file 'Female.strings'

This ensures the most flexibility and gives you a solution that doesn't require you to define entries for BOTH cases. This is actually really useful for your case as not all phrases may have feminine forms.

As a result, the following solution doesn't require duplicate entries, which is pretty cool!

First define your macro:

#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]

Then define the expanded function as such:

+ (NSString*)SXLocalizedString:(NSString*)str with:(NSString*)comment {
    NSString* feminine = NSLocalizedStringFromTable(str, @"Female", comment);
    NSString* value = NSLocalizedString(str, comment);
    if ([self userIsFemale] &&
        feminine) {
        // choose the feminine version of the string
        value = feminine;
    }
    return value;
}
尘世孤行 2024-11-26 01:46:52

几年来,Xcode 已经有了 LOCALIZED_STRING_MACRO_NAMES,因此您可以放置​​自定义的 NSLocalizedString 替代宏名称(如果它们遵循相同的参数结构),并且 Xcode 会正确导出/导入它们,类似于 < a href="https://stackoverflow.com/a/15732244/2105993">genstrings 答案

For couple of years Xcode has LOCALIZED_STRING_MACRO_NAMES, so you can put your custom NSLocalizedString alternative macro names if they follow same parameters structure and Xcode will correctly export/import them, similar to genstrings answer

豆芽 2024-11-26 01:46:51

这是我的自定义实现,它使用 NSLocalizedString 并使用注释作为默认值:

(NSLocalizedStringWithDefaultValue 不能与 genstring 正常工作,这就是我提出这个解决方案的原因)

1 。在预编译头文件(.pch 文件)中,重新定义“NSLocalizedString”宏:

// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key  comment:_comment]

2.创建一个类来实现本地化处理程序

#import "LocalizationHandlerUtil.h"

@implementation LocalizationHandlerUtil

static LocalizationHandlerUtil * singleton = nil;

+ (LocalizationHandlerUtil *)singleton
{
    return singleton;
}

__attribute__((constructor))
static void staticInit_singleton()
{
    singleton = [[LocalizationHandlerUtil alloc] init];
}

- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
    // default localized string loading
    NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];

    // if (value == key) and comment is not nil -> returns comment
    if([localizedString isEqualToString:key] && comment !=nil)
        return comment;

    return localizedString;
}

@end

3.使用它!

确保在应用程序构建阶段添加运行脚本,以便您的 Localized.strings 文件将在每次构建时更新,即新的本地化字符串将添加到您的 Localized.strings 文件中:

我的构建阶段脚本是一个 shell 脚本:

Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder

因此,当您在代码中添加此新行时:

self.title = NSLocalizedString(@"view_settings_title", @"Settings");

然后执行构建,您的 ./Localized.scripts 文件将包含此新行:

/* Settings */
"view_settings_title" = "view_settings_title";

由于 'view_settings_title' 的 key == value,因此自定义LocalizedStringHandler 将返回注释,即“设置”

Voilà :-)

Here is my Custom implementation that use NSLocalizedString that use comment as default value:

(NSLocalizedStringWithDefaultValue does not work properly with genstring, that's why I proposed this solution)

1 . In your pre compiled header (.pch file) , redefine the 'NSLocalizedString' macro:

// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key  comment:_comment]

2. create a class to implement the localization handler

#import "LocalizationHandlerUtil.h"

@implementation LocalizationHandlerUtil

static LocalizationHandlerUtil * singleton = nil;

+ (LocalizationHandlerUtil *)singleton
{
    return singleton;
}

__attribute__((constructor))
static void staticInit_singleton()
{
    singleton = [[LocalizationHandlerUtil alloc] init];
}

- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
    // default localized string loading
    NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];

    // if (value == key) and comment is not nil -> returns comment
    if([localizedString isEqualToString:key] && comment !=nil)
        return comment;

    return localizedString;
}

@end

3. Use it!

Make sure you add a Run script in your App Build Phases so you Localizable.strings file will be updated at each build, i.e., new localized string will be added in your Localized.strings file:

My build phase Script is a shell script:

Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder

So when you add this new line in your code:

self.title = NSLocalizedString(@"view_settings_title", @"Settings");

Then perform a build, your ./Localizable.scripts file will contain this new line:

/* Settings */
"view_settings_title" = "view_settings_title";

And since key == value for 'view_settings_title', the custom LocalizedStringHandler will returns the comment, i.e. 'Settings"

Voilà :-)

禾厶谷欠 2024-11-26 01:46:51

NSLocalizedString 只是 NSBundle.h 中定义的宏
重新定义它或创建一个新的,例如 NSGenderAwareLocalizedString 以满足您的需求。

使用新的宏,您可以自由地做任何您想做的事情:每种语言两个字符串文件,一个用于男性,一个用于女性。或者,您可以定义一个约定,从男性本地化字符串的键中派生出女性本地化字符串的键。

NSLocalizedString is just a macro defined in NSBundle.h
Redefine it or create a new one, for example NSGenderAwareLocalizedString to fit your needs.

With the new macro, you are free to do whatever you want: two strings files per language, one for male and one for female. Or you can define a convention to derivate the key for a localized string for a female from the key of the male localized string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文