20

我有一个使用 CocoaPods 的项目。结果,我有一个包含两个项目的工作区:我的和 Pods。

Pods 包含我想要本地化的代码,并且我.strings在 Pod 中创建了文件。但是,NSLocalizedString无法加载这些字符串。我怀疑这是因为.strings文件不在主包中,但没有 Pod 包,因为它被编译成静态库。

有没有比我的主项目更好的方法来本地化 CocoaPods 项目中的代码?

4

5 回答 5

12

NSLocalizedString只是调用 NSBundle 的localizedStringForKey:value:table:,所以我写了一个 NSBundle 类别来查看几个包(在 iOS 中只是文件夹):

NSString * const kLocalizedStringNotFound = @"kLocalizedStringNotFound";

+ (NSString *)localizedStringForKey:(NSString *)key
                              value:(NSString *)value
                              table:(NSString *)tableName
                       backupBundle:(NSBundle *)bundle
{
    // First try main bundle
    NSString * string = [[NSBundle mainBundle] localizedStringForKey:key
                                                               value:kLocalizedStringNotFound
                                                               table:tableName];

    // Then try the backup bundle
    if ([string isEqualToString:kLocalizedStringNotFound])
    {
        string = [bundle localizedStringForKey:key
                                         value:kLocalizedStringNotFound
                                         table:tableName];
    }

    // Still not found?
    if ([string isEqualToString:kLocalizedStringNotFound])
    {
        NSLog(@"No localized string for '%@' in '%@'", key, tableName);
        string = value.length > 0 ? value : key;
    }

    return string;
}

然后NSLocalizedString在我的前缀文件中重新定义宏:

#undef  NSLocalizedString
#define NSLocalizedString(key, comment) \
[NSBundle localizedStringForKey:key value:nil table:@"MyStringsFile" backupBundle:AlternativeBundleInsideMain]

如果需要,其他宏也一样(即NSLocalizedStringWithDefaultValue

于 2013-04-25T08:34:54.570 回答
5

@Rivera Swift 2.0版本:

static let kLocalizedStringNotFound = "kLocalizedStringNotFound"

static func localizedStringForKey(key:String,
                                  value:String?,
                                  table:String?,
                                  bundle:NSBundle?) -> String {
    // First try main bundle
    var string:String = NSBundle.mainBundle().localizedStringForKey(key, value: kLocalizedStringNotFound, table: table)

    // Then try the backup bundle
    if string == kLocalizedStringNotFound {
        string = bundle!.localizedStringForKey(key, value: kLocalizedStringNotFound, table: table)
    }

    // Still not found?
    if string == kLocalizedStringNotFound {
        print("No localized string for '\(key)' in '\(table)'")
        if let value = value {
            string = value.characters.count > 0 ? value : key
        } else {
            string = key
        }
    }

    return string;
}
于 2015-07-29T08:21:02.523 回答
2
  1. 您不应该在 Pods 项目中放置任何文件,因为该pod命令会一次又一次地重新创建项目。

    所以把字符串文件放在你自己的项目中。

  2. 如果你想在你自己的 Pod中发布本地化的字符串文件,你应该将它包含在一个包中,并确保该包将安装在你的 Podspec 文件中。

例如:

def s.post_install(target)
    puts "\nGenerating YOURPOD resources bundle\n".yellow if config.verbose?
    Dir.chdir File.join(config.project_pods_root, 'YOURPOD') do
        command = "xcodebuild -project YOURPOD.xcodeproj -target YOURPODResources CONFIGURATION_BUILD_DIR=../Resources"
        command << " 2>&1 > /dev/null" unless config.verbose?
        unless system(command)
            raise ::Pod::Informative, "Failed to generate YOURPOD resources bundle"
        end

        File.open(File.join(config.project_pods_root, target.target_definition.copy_resources_script_name), 'a') do |file|
            file.puts "install_resource 'Resources/YOURPODResources.bundle'"
        end
    end
end
于 2013-02-27T14:51:42.067 回答
2

在 pod 中本地化资源的最佳方法(公共或私有无关)是将.strings本地化文件添加到 pod 包中。

主应用程序在从 pod 框架中获取本地化文件时非常挑剔,您必须遵循以下步骤:

1 - 创建 Localizable.strings 和本地化*.strings所需的所有其他文件,并将它们放在一个文件夹中,如下所示:

字符串文件夹结构

需要遵守的一些限制条件:

  • 文件夹名称必须是XX.lproj,其中 XX 是您的确切语言名称,注意:en!= en-GB!=en-US
  • 所有lproj文件夹都需要在同一级别
  • 每个lproj文件夹需要有相同数量的.strings文件和相同的名称

2 - 配置您的.podspec文件,以便 pod 可以正确获取本地化并将它们复制到.framework.

例子:

  s.resource = 'your_path/Localizations/**/*', '... possibly other resources'

在您的 Development Pods 文件夹中执行pod install结果后应该是这样的:

在此处输入图像描述

要检查的一件重要事情是,创建的框架是所有.lproj文件夹都必须位于根文件夹中,否则主应用程序不会正确拾取。

3 - 在您的 pod 代码中,NSLocalizedString您必须使用NSLocalizedStringFromTableInBundle

NSLocalizedStringFromTableInBundle(@"My string", nil, [NSBundle bundleForClass:[MCLoginContext class]], @"String context")

整个过程非常微妙和烦人,但仅此而已。

于 2020-07-24T13:31:32.637 回答
-1

为了快速,您可以使用 Loc 枚举:

enum Loc : String{
case ok = "OK"
case cancel = "Cancel"

var localized: String {
    let s = self.rawValue
    let bundle = Bundle(for: <classname inside the bundle>.self)
    let result = NSLocalizedString(s, tableName: nil, bundle: bundle, value: "", comment: "")
    return result;
}

}

并这样使用它:

let s = Loc.ok.localized
print(s)
于 2020-09-09T13:14:38.267 回答