原文连接python
随着项目愈来愈成熟,逐渐拓展到海外市场,咱们就须要适配多种国际化和地区、须要对本身的产品进行国际化,让更多的用户可使用咱们的APP,这就须要对咱们的产品进行国际化了。在这里就介绍一下本身在国际化项目里面踩过的一些坑。ios
在之前调用的地方咱们须要替换为本地化调用方式 好比之前咱们是这么调用的:安全
NSString *tips = @"wait";
复制代码
如今要换成ruby
NSString *tips = NSLocalizedString(@"wait", nil);
复制代码
(ps 第二个是为了方便翻译人员理解上下文语境使用的 。)app
而后在stirng文件内添加对应的字符串:模块化
"wait" = "别着急";
复制代码
你能够在不一样的文件添加对应不一样语言的翻译 。测试
让咱们看下这个宏的定义 :ui
#define NSLocalizedString(key, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \
[bundle localizedStringForKey:(key) value:(val) table:(tbl)]
复制代码
能够看到实际上就是从mainBundle中取出了指定的String文件 , 而后根据咱们在代码中定义的 ‘key’ 值取出valuespa
有的时候咱们要指定咱们的string文件名字而不使用上面的那个默认名字 。翻译
NSString *tips = NSLocalizedStringFromTableInBundle(@"wait", @"TDFOSLocalizable", [NSBundle bundleForClass:[self class]], @"some tips to tell user wait");
复制代码
这里面多出来两个参数,第一个是咱们要指定的string文件名字,第二个就是要从哪一个bundle中取,这个bundle的问题咱们下面就会讲到。
那么在咱们工程很大的状况下咱们要把所有的字符串都替换为前缀为NSLocalizedString的形式人工手动替换确定是不行的,又慢又不安全,没准复制粘贴的时候还把原来的key改错了,这里贴一段python的实例代码,能够稍加改动运行替换工程中的string前缀 。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import re
import sys
import datetime
folderPath = '/Users/felix/Documents/2dfire/TDFOpenShop/TDFOpenShop/Classes'
stringToReplace = 'NSLocalizedString'
stringReplaceTo = 'TDFOSLocalizedString'
def scan_files(rootdir):
files = []
for parent, dirnames, filenames in os.walk(rootdir):
for filename in filenames:
if len(filename.split('.',1))>1:
if filename.split('.',1)[1] == 'm':
files.append(os.path.join(parent, filename))
return files
def replaceStringIn(file):
code = open(file,'r+')
text = code.read()
code.seek(0,0)
code.write(text.replace(stringToReplace,stringReplaceTo))
code.close()
def main():
files = scan_files(folderPath)
for filePath in files:
replaceStringIn(filePath)
if __name__ == '__main__':
main()
复制代码
这里面我是把之前的NS开头的宏替换为自定义的宏 , 大同小异 , 能够参照这个修改下便可 。
当咱们所有修改好之后确定是要测试下显示对不对的、有两种方法能够快速切换App语言
不少时候咱们的工程体量大到必定程度的时候都会模块化掉,几我的或者一我的负责一个模块,而有的模块是要做为SDK提供外部interface使用的 。当你把SDK提供出去的时候,咱们指望的效果是在其余人(其余工程)内部运行的、咱们的SDK也可以国际化显示 。可是在咱们整个工程的string文件包含几千上万条的时候显然不须要所有移动到模块内 。
因此在这里面咱们要作的就是把须要的使用到的字符串和翻译好的value从主工程迁移到模块内部 。
咱们先把主工程的国际化文件的文件夹复制到咱们的模块路径下面,在模块内部有一个配置文件 x.podspec
里面添加这样一段配置
s.resources = 'xxx/*.{xib,jpg,png,xcassets}','xxx/*.lproj'
复制代码
主要注意后面 , 这里就把咱们刚复制来的国际化问价加入了模块的资源中 ,这时 ,若是咱们不想用跟主工程同样的名字 ,Localizable.strings ,能够把这个名字也给改掉 , 好比 abc.strings
这里为了有别于主工程的国际化 , 咱们把strings文件更名为 abc.strings 而后在模块内新建一个头文件
#ifndef TDFOSLocalizeMacro_h
#define TDFOSLocalizeMacro_h
#define TDFOSLocalizedString(key, comment) \
NSLocalizedStringFromTableInBundle(key, @"abc", [NSBundle bundleForClass:[self class]], comment)
#endif /* TDFOSLocalizeMacro_h */
复制代码
这里可使用上面的脚本再次替换字符串前缀,而后运行下看看是否替换成功。 这里注意要从新pod install下,不然cocoapods不会帮咱们把资源引入包内 。 ps: 别忘了删掉主工程中移除来的字符串 !!!
基本用法暂时介绍到这里 , 关于模块化和国际化的东西要多了解一下NSbundle这个类 。