关于我:大厂摸鱼 + 业余独立开发,之后会输出深度技术文章 + 独立开发技巧

我的往期技术文章合集:RickeyBoy – Gitbub

我的独立开发 App:iColors – 规划创意 配色帮手

上一篇:

独立开发之 App 国际化全过程(一):为什么要做国际化

独立开发之 App 国际化全过程(二):App 数据翻译

独立开发之 App 国际化全过程(三):Core Data 模型升级

独立开发之 App 国际化全过程(四):Core Data 模型解析

独立开发之 App 国际化全过程(五):提取 App 中文本案牍

独立开发之 App 国际化全过程(六):替换代码中运用的文本

独立开发之 App 国际化全过程(七):App 内言语环境建立

App 内言语细节适配

咱们做完了前文所说的全部,现在整个 App 应该绝大部分内容都现已适配多言语了。大的框架现已完结,剩下的是一些细节优化与调整,有部分特别的场景需求额外的进行适配。

系统权限案牍的适配

独立开发之 App 国际化全过程(八):App 内言语细节适配

除了 App 自身内容支撑多言语之外,类似于这样的权限内容也需求支撑多言语。那咱们怎样去设置呢?其实原理和 Localizable.strings 的原理是共同的,只不过此时咱们需求一个新的文件,叫做 InfoPlist.strings,用来专门为 InfoPlist 中的内容做多言语的适配。

独立开发之 App 国际化全过程(八):App 内言语细节适配

支撑简体中文和英文的,完整 Localizable 文件应该如上图所示。接下来咱们只需求运用 InfoPlist 中的 key 作为key,Xcode 会自动为咱们匹配对应的翻译案牍,完结上图所示多言语作用。比方,咱们要运用保存图片的权限,这个权限在 InfoPlist 中对应的 key 是 NSPhotoLibraryAddUsageDescription:

独立开发之 App 国际化全过程(八):App 内言语细节适配

那么咱们进行如下的配置,就功德圆满了!

// InfoPlist (Chinese, Simplified)
"NSPhotoLibraryAddUsageDescription" = "咱们需求此权限用于保存您喜爱的内容";
// InfoPlist (English)
"NSPhotoLibraryAddUsageDescription" = "Allow photo library access to save your favorite color palettes";

小组件案牍适配

除了主 App 自身的案牍,还有一部分是小组件中运用的案牍。适配这部分的案牍非常简略,不需求做额外的处理,把翻译案牍相同放到 Localizable.strings 中即可。

不过这儿涉及到一个新的问题,就是如何将主 App 中的言语选择,同步到 Widget 小组件中?我选用的是通过 AppGroupUserDefaults 的计划。信任之前完结了小组件功能的情况下,大概率现已完结通过 AppGroup 进行数据互通了,这儿我就不再赘述具体的完结办法。

需求注意的是,咱们如果在 App 中选择了新言语,更改了言语环境之后需求通知小组件进行改写:

WidgetCenter.shared.reloadTimelines(ofKind: "CodeModulesWidget")

自动换算时刻信息

当我运用脚本查看未翻译的内容时,发现漏网之鱼:在 iColors App 中,有部分场景运用到了时刻信息,包含月份和星期,如下图所示。

独立开发之 App 国际化全过程(八):App 内言语细节适配

这部分内容如果要依照之前的办法,在 Localizable.strings 中完结对应的翻译也是不难的,不过稍显繁琐。那么有没有更好的办法呢?

其实 Locale 自身内置了依据多言语,回来对应日期的办法,咱们这儿以月份为例,用这样的方法可以获取到当前月份的正确表达。

func currentMonth(for locale: Locale) -> String {
    let calendar = Calendar.current
    let month = calendar.component(.month, from: self)
​
    let dateFormatter = DateFormatter()
    dateFormatter.locale = locale
​
    if let monthSymbols = dateFormatter.standaloneMonthSymbols {
        let monthSymbol = monthSymbols[month - 1]
        return monthSymbol
    } else {
        return ""
    }
}

结语

到这儿,本篇总算完结了。一方面完结如此大工程的一个项目,我也想尽量将我的效果记录下来;另一方面,也期望这些内容能对读者有所协助。

感谢我们的阅览,如果有任何问题,可以给我留言,我会尽量解答。