iOS-International

原文連接python

隨着項目愈來愈成熟,逐漸拓展到海外市場,咱們就須要適配多種國際化和地區、須要對本身的產品進行國際化,讓更多的用戶可使用咱們的APP,這就須要對咱們的產品進行國際化了。在這裏就介紹一下本身在國際化項目裏面踩過的一些坑。ios

Project配置


  • 打開你的工程 , 在左側欄選中project
  • 在打開的面板中選中project下的藍色圖標
  • 找到Localizations選項 , 添加你須要國家化的語言
  • 在主工程下command + N 新建Localizable.string文件
  • 選中你建立的string文件 , 打開右側面板
  • 點擊Localization組下的Localize按鈕
  • 把你剛纔配置在工程內的選項添加進去就好。

調用方式


在之前調用的地方咱們須要替換爲本地化調用方式 好比之前咱們是這麼調用的:安全

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語言

  • 打開模擬器或真機 general -> setting -> lang ,不過這樣比較繁瑣。
  • 點擊導航欄上的模擬器圖標左邊的schema選項,選擇editSchema -> Run -> Options ->Application Language 直接改成你須要驗證的語言運行就能夠啦 。

如何在模塊內單獨配置國際化文件


不少時候咱們的工程體量大到必定程度的時候都會模塊化掉,幾我的或者一我的負責一個模塊,而有的模塊是要做爲SDK提供外部interface使用的 。當你把SDK提供出去的時候,咱們指望的效果是在其餘人(其餘工程)內部運行的、咱們的SDK也可以國際化顯示 。可是在咱們整個工程的string文件包含幾千上萬條的時候顯然不須要所有移動到模塊內 。

因此在這裏面咱們要作的就是把須要的使用到的字符串和翻譯好的value從主工程遷移到模塊內部 。

  • 解決方案:使用cocoapods集成的模塊化內部進行國際化

咱們先把主工程的國際化文件的文件夾複製到咱們的模塊路徑下面,在模塊內部有一個配置文件 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這個類 。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息