iOS子組件多語(yǔ)言適配(三)

一、 前言

在產(chǎn)品進(jìn)行國(guó)際化的過(guò)程中,多語(yǔ)言適配是必不可少的環(huán)節(jié),前期我們把項(xiàng)目中所有的多語(yǔ)言翻譯放到了項(xiàng)目主工程中,各個(gè)組件直接去使用并沒(méi)有什么問(wèn)題(我們的項(xiàng)目架構(gòu)是:本地組件 + 私有公共組件),但是有一些公共的模塊,要在多個(gè)項(xiàng)目中使用,同時(shí)也要做多語(yǔ)言適配,就需要把適配文件放到每個(gè)子組件中去處理。

二、組件添加多語(yǔ)言適配

在適配多語(yǔ)言的過(guò)程中我們嘗試了兩種解決方案:

方案一:

1、首先用 pod lib create multilingualModule 命令創(chuàng)建一個(gè)組件
2、選中 pods 項(xiàng)目,創(chuàng)建一個(gè) Localizable.strings 文件
3、根據(jù)以下步驟添加需要適配的多語(yǔ)言

image.png

4、把創(chuàng)建的多語(yǔ)言文件放到組件的 Assets 文件中,如圖:
image02.png

至此,適配多語(yǔ)言的流程都已經(jīng)完成,經(jīng)過(guò)測(cè)試,可以順利的加載到需要適配的語(yǔ)言
按照 cocoapods 官方提倡的方式加載資源文件,在podspec文件中添加下面的代碼

  s.resource_bundles = {
     'multilingualModule' => ['multilingualModule/Assets/*']
  }
方案二:

1、首先創(chuàng)建一個(gè)與組件同名的 bundle ,并把組件放到組件的 Assets 文件中


image03.png

2、把按照方案一創(chuàng)建好的多語(yǔ)言文件放到創(chuàng)建好的bundle中 ,如圖:


image04.png

3、在 podspec 文件中,把之前加載資源的方式改成下面這句代碼:
   s.resource = 'multilingualModule/multilingualModule.bundle'

有人就會(huì)問(wèn)為什么不用官方推薦的方式加載資源了?

  s.resource_bundles = {
    'multilingualModule' => ['multilingualModule/Assets/*']
  }

如果用這種方式加載資源,組件被編譯后,就會(huì)出現(xiàn)如下的情況,multilingualModule.bundle 中還包含一個(gè) multilingualModule.bundle ,顯然,這不是我們期望的結(jié)果,且通過(guò)以下方式查看:
在項(xiàng)目編譯的產(chǎn)物中找到 multilingualModule_Example.app ,并右鍵顯示包內(nèi)容,如圖:


image05.png

繼續(xù)右鍵顯示包內(nèi)容,可以看到我們添加的多語(yǔ)言文件被包含在內(nèi)層的bundle中,如圖:


image06.png

雖然這種方式也可以正常發(fā)布組件,但是我們是希望把所有的資源只包含在一個(gè) bundle中,便于我們管理

三、如何在組件中使用翻譯文件

如果我們把翻譯文件放到主工程中,通過(guò)mainbundle 的方式直接加載即可:

 func localValue(str:String) -> String{
    let bundle:Bundle = Bundle.main
    return bundle.localizedString(forKey: str, value: nil, table: "Localizable")
 }

但是組件中的資源文件,在編譯的之后,并沒(méi)有被放到 mainbundle 路徑,需要先找到 multilingualModule.bundle 然后再獲取資源文件,通過(guò)以下方式獲取

    /// 加載組件內(nèi)部的多語(yǔ)言(默認(rèn)必須添加一個(gè)英文的多語(yǔ)言)
    /// - Parameters:
    ///   - sourceCls: 當(dāng)前組件內(nèi)部的任意類文件
    ///   - txtStr: 需要翻譯的文本的 key
    /// - Returns: 翻譯后的文本
    func localValueWithModule(_ sourceCls: AnyClass,_ txtStr:String)->String{
        var crBundle:Bundle? = nil
        let sourceClsString = NSStringFromClass(sourceCls)
        let list = sourceClsString.components(separatedBy: ".")
        let frameWorkBundle = Bundle(for: sourceCls)
        let resource = list[0]
        if let url = frameWorkBundle.url(forResource: resource, withExtension: "bundle"){
            crBundle = Bundle.init(url: url)
        }
        
        if crBundle != nil {
            let path = crBundle?.path(forResource: getCurrLanString(), ofType: "lproj")
            if path?.count ?? 0 > 0 {
                //用這個(gè)路徑生成新的bundle
                let bundle = Bundle(path: path!)!
                let mes = bundle.localizedString(forKey: txtStr, value: nil, table: "Localizable")
                return mes
            }
        }
        return txtStr
    }

注意:getCurrLanString() 獲取當(dāng)前需要翻譯的多語(yǔ)言

四、總結(jié)

在做子組件多語(yǔ)言適配的過(guò)程中也遇到了一些奇怪的問(wèn)題,這里把正確的流程思路記錄下,供有需求的同學(xué)參考~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容