我有一个使用 CocoaPods 的项目。结果,我有一个包含两个项目的工作区:我的和 Pods。
Pods 包含我想要本地化的代码,并且我.strings
在 Pod 中创建了文件。但是,NSLocalizedString
无法加载这些字符串。我怀疑这是因为.strings
文件不在主包中,但没有 Pod 包,因为它被编译成静态库。
有没有比我的主项目更好的方法来本地化 CocoaPods 项目中的代码?
我有一个使用 CocoaPods 的项目。结果,我有一个包含两个项目的工作区:我的和 Pods。
Pods 包含我想要本地化的代码,并且我.strings
在 Pod 中创建了文件。但是,NSLocalizedString
无法加载这些字符串。我怀疑这是因为.strings
文件不在主包中,但没有 Pod 包,因为它被编译成静态库。
有没有比我的主项目更好的方法来本地化 CocoaPods 项目中的代码?
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
)
@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;
}
您不应该在 Pods 项目中放置任何文件,因为该pod
命令会一次又一次地重新创建项目。
所以把字符串文件放在你自己的项目中。
如果你想在你自己的 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
在 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")
整个过程非常微妙和烦人,但仅此而已。
为了快速,您可以使用 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)