公司 app 进行本地化,发现 pod 本地化与直接在 project 本地化还是有差异的,这里以英文和简体中文本地化作为例子。文章最后提供了 pod 本地化的工具类。
一、添加多语言文字
1、创建多语言文件夹
多语言文件夹采用语言的编码和 .lproj 作为文件夹名称。例如英文的为 en.lproj 。语言的编码可以从苹果官网查询到。当然也可以自定义编码,这里不做讨论,因为读取本地文本的方式只和文件夹名称有关,只要配置正确就可以。
en.lproj 和 zh-Hant.lproj 的文件夹效果如下:
2、创建 strings 文件
可以使用系统提供的 Strings file 创建,也可以使用空文件创建
将语言文件放到相应的语言编码文件夹下。效果如下:
3、添加语言键值对
把 PodTest.strings 通过 ASCII property list 的方式打开.然后添加语言键值对如下图:
注意:尽量不要以source code的方式编译,容易出现编译错误,如果出现错误可以用这个命令检查下
/usr/bin/plutil -lint PodTest/Resource/en.lproj/PodTest.strings
4、podspec路径配置
s.resource_bundles = {
'SLTLocalizeTest' => ['SLTLocalizeTest/LocalizedStrings/*.lproj/*']
}
注意:路径要设置到lproj级别,这样 xcode 对多语言文件的显示会geng’j更加友好,同时编译进 app 后的多语言文件将是二进制格式。如果这样配置 LocalizedStrings/* ,打包后的 strings 文件将是明文形式,并且 lproj 文件只是作为普通文件显示到 xcode 中。
5、本地语言读取代码示例
- (NSString *)bundleString:(NSString *)key{
NSBundle *bundle = [self.class bundleInFramework:@"PodTest.framework" bundleName:@"PodTestLong.bundle"];
NSString *testString = NSLocalizedStringFromTableInBundle(key, @"PodInterLong", bundle, nil);
return testString;
}
/**
* 读取framework中的bundle
*
* @param framework bundle所在的framewok的名称
* @param bundleName bundle的名称
*
* @return 如果存在则返回bundle,不存在则返回nil
*/
+ (NSBundle *)bundleInFramework:(NSString *)framework bundleName:(NSString *)bundleName {
if ([framework length] == 0 || [bundleName length] == 0) {
return nil;
}
NSString *tempFramework = [framework copy];
NSString *frameExtension = @".framework";
if (![framework hasSuffix:frameExtension]) {
tempFramework = [framework stringByAppendingString:frameExtension];
}
NSString *tempBundle = [bundleName copy];
NSString *bundleExtension = @".bundle";
if (![bundleName hasSuffix:bundleExtension]) {
tempBundle = [bundleName stringByAppendingString:bundleExtension];
}
NSString*path = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:framework];
NSBundle *bundle = [NSBundle bundleWithPath:[path stringByAppendingPathComponent:tempBundle]];
return bundle;
}
二、添加多语言图片
1、文件夹的创建方式与文本的相同
直接手动创建添加后缀或者点击 xcode 的 localize 按钮创建即可
2、添加多语言图片
将名称相同的图片放到相应的编码文件下即可
3、路径配置
s.resource_bundles = {
'SLTLocalizeTest' => ['SLTLocalizeTest/LocalizedImages/*.lproj/*.png','SLTLocalizeTest/LocalizedStrings/*.lproj/*']
}
注意:建议配置到lrpoj级别
4、示例代码
+ (UIImage *)localizedImage:(NSString *)imageName inBundle:(NSString *)bundleName {
if (imageName.length == 0) return nil;
if ([imageName hasSuffix:@"/"]) return nil;
NSString *res = imageName.stringByDeletingPathExtension;
NSString *ext = imageName.pathExtension;
NSString *path = nil;
CGFloat scale = 1;
NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpg"];
NSArray *scales = _ONENSBundlePreferredScales();
NSBundle *tmp = ONEBundleWithName(bundleName);
NSString *language = [ONEUserLanguageManager currentLanguage];
NSString *fileNamePrefix = DILanguageCodeToISO639(language);
if (![ONEValidJudge isValidString:fileNamePrefix]) {
DDLogError(@"语言编码转化错误:%@",fileNamePrefix);
return nil;
}
NSString *bundlePath = [tmp pathForResource:fileNamePrefix ofType:@"lproj"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
for (int s = 0; s < scales.count; s++) {
scale = ((NSNumber *)scales[s]).floatValue;
NSString *scaledName = _ONENSStringByAppendingNameScale(res, scale);
for (NSString *e in exts) {
path = [bundle pathForResource:scaledName ofType:e];
if (path) break;
}
if (path) break;
}
if (path.length == 0) return nil;
NSData *data = [NSData dataWithContentsOfFile:path];
if (data.length == 0) return nil;
return [[UIImage alloc] initWithData:data scale:scale];
}
三、pod 本地化工具类
由于该需求很具有通用性,因此将该功能封装成了一个 cocoapod 工具。仓库地址如下:https://github.com/LiuShulong/SLTLocalizeKit