MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Swift本地化与国际化

2021-11-023.2k 阅读

本地化与国际化基础概念

在软件开发中,本地化(Localization)和国际化(Internationalization)是让应用能够适应不同地区和语言用户的关键技术。国际化是指设计应用程序的过程,使其能够支持多种语言和地区,而无需对代码进行重大修改。本地化则是将国际化的应用针对特定地区或语言进行定制,包括翻译文本、调整日期和数字格式、适配图像和布局等。

在Swift开发中,通过使用一些系统框架和遵循特定的约定,可以方便地实现应用的本地化和国际化。

本地化字符串

本地化字符串是应用国际化的基础。在Swift中,主要通过NSLocalizedString宏来实现字符串的本地化。

首先,在项目的Info.plist文件中,需要配置支持的语言。打开Info.plist,添加一个新的键CFBundleLocalizations,它是一个数组类型,在数组中添加你想要支持的语言代码,比如en(英语)、zh-Hans(简体中文)等。

接下来,创建本地化字符串文件。在项目导航器中,右键点击项目文件夹,选择New File...,在弹出的对话框中选择Resource -> Strings File,命名为Localizable.strings。然后,根据支持的语言,为该文件创建不同的语言版本。在项目导航器中选中Localizable.strings,在右侧的属性检查器中,点击Localize...按钮,选择要本地化的语言。

Localizable.strings文件中,按照以下格式书写键值对:

"key" = "value";

例如,在英文版本的Localizable.strings中:

"greeting" = "Hello";

在简体中文版本的Localizable.strings中:

"greeting" = "你好";

在Swift代码中,使用NSLocalizedString来获取本地化字符串:

let greeting = NSLocalizedString("greeting", comment: "A simple greeting")
print(greeting)

NSLocalizedString的第一个参数是键,第二个参数是注释,注释用于帮助翻译人员理解该字符串的用途。

本地化日期和数字格式

日期格式

Swift中使用DateFormatter来处理日期格式的本地化。DateFormatter会根据当前用户的区域设置来格式化日期。

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
let localizedDateString = dateFormatter.string(from: date)
print(localizedDateString)

在上述代码中,dateStyletimeStyle属性可以设置为不同的样式,如.full.long.medium.short等。如果想要使用特定区域的日期格式,可以设置dateFormatter.locale属性。

let frenchLocale = Locale(identifier: "fr_FR")
dateFormatter.locale = frenchLocale
let frenchDateString = dateFormatter.string(from: date)
print(frenchDateString)

数字格式

对于数字格式化,使用NumberFormatter。同样,它会根据用户的区域设置来格式化数字。

let number = 12345.678
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let localizedNumberString = numberFormatter.string(from: NSNumber(value: number))
print(localizedNumberString)

numberStyle可以设置为不同的样式,如.currency(货币格式)、.percent(百分比格式)等。也可以通过设置locale属性来使用特定区域的数字格式。

let germanLocale = Locale(identifier: "de_DE")
numberFormatter.locale = germanLocale
let germanNumberString = numberFormatter.string(from: NSNumber(value: number))
print(germanNumberString)

本地化图像

为不同语言或地区提供不同的图像也是本地化的一部分。在项目中,可以通过创建资产目录(Asset Catalog)并利用其本地化功能来实现。

首先,在项目导航器中,确保有一个资产目录(通常命名为Assets.xcassets)。如果没有,可以通过右键点击项目文件夹,选择New File...,然后在Resource中选择Asset Catalog来创建。

在资产目录中,创建一个新的图像集(Image Set)。假设我们要为应用的图标提供不同语言版本,创建一个名为AppIcon的图像集。

选中图像集,在右侧的属性检查器中,点击Localize...按钮,选择要本地化的语言。然后,针对不同语言版本,将对应的图像拖放到相应的位置。

在代码中,使用图像时,直接引用图像集的名称即可。

let image = UIImage(named: "AppIcon")
if let image = image {
    // 使用图像
}

系统会根据当前用户的语言设置自动加载正确的图像。

本地化故事板和XIB文件

故事板(Storyboard)和XIB文件中的文本也需要本地化。

在Interface Builder中,选中要本地化的控件,比如一个按钮,在属性检查器中,找到Title属性,点击右侧的小箭头,选择Localize...。这会在Localizable.strings文件中为该文本创建一个键值对。

然后,按照前面介绍的Localizable.strings文件的本地化方法,为不同语言版本翻译这些字符串。

国际化布局

不同语言的文本长度和书写方向可能不同,因此应用的布局需要能够适应这些变化。在Swift中,使用自动布局(Auto Layout)和大小类(Size Classes)可以有效地实现国际化布局。

自动布局

自动布局通过约束(Constraints)来定义视图之间的关系,确保在不同设备和方向下视图能够正确显示。例如,在一个视图中,有一个按钮和一个文本标签,我们可以通过以下方式添加约束:

let button = UIButton(type: .system)
button.setTitle("Click Me", for: .normal)
view.addSubview(button)

let label = UILabel()
label.text = "Some text"
view.addSubview(label)

button.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    label.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 20),
    label.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])

这样,无论设备的大小和方向如何,按钮和标签都会保持正确的相对位置。

大小类

大小类(Size Classes)允许我们根据设备的屏幕尺寸和方向定义不同的布局。在Interface Builder中,可以通过选择不同的大小类组合来设计布局。例如,在iPhone的竖屏和横屏模式下,可能需要不同的布局。

在故事板中,点击画布下方的大小类切换按钮,可以选择不同的大小类组合。然后,在不同的大小类组合下,可以为视图添加不同的约束和设置不同的属性,以实现自适应布局。

处理从右到左(RTL)语言

一些语言,如阿拉伯语和希伯来语,是从右到左书写的。Swift提供了对RTL语言的支持。

在项目的Info.plist文件中,添加一个新的键UIUserInterfaceLayoutDirection,并将其值设置为RTL,可以强制应用采用从右到左的布局方向。

在代码中,可以通过UIViewsemanticContentAttribute属性来控制视图的布局方向。

let view = UIView()
view.semanticContentAttribute = .forceRightToLeft

对于文本视图,如UILabelUITextField,也可以设置textAlignment属性为.right,以确保文本正确对齐。

let label = UILabel()
label.textAlignment = .right

动态本地化

有时候,应用需要在运行时动态切换语言。在Swift中,可以通过以下步骤实现动态本地化。

首先,创建一个函数来更新应用的语言设置。

func setLanguage(_ language: String) {
    UserDefaults.standard.set([language], forKey: "AppleLanguages")
    UserDefaults.standard.synchronize()
    NotificationCenter.default.post(name: Notification.Name("LanguageChanged"), object: nil)
}

上述函数将新的语言代码存储在UserDefaults中,并发送一个通知LanguageChanged

然后,在需要监听语言变化的地方,注册这个通知。

NotificationCenter.default.addObserver(self, selector: #selector(updateLocalization), name: Notification.Name("LanguageChanged"), object: nil)

updateLocalization方法中,重新加载本地化字符串和更新界面。

@objc func updateLocalization() {
    // 重新加载本地化字符串
    let greeting = NSLocalizedString("greeting", comment: "A simple greeting")
    // 更新界面上的文本
    label.text = greeting
}

这样,当调用setLanguage函数时,应用会动态切换语言并更新界面。

本地化测试

为了确保应用的本地化功能正常,需要进行全面的测试。

  1. 文本翻译测试:检查所有本地化字符串是否正确翻译,特别是那些包含占位符或复数形式的字符串。
  2. 布局测试:在不同语言和设备上测试应用的布局,确保视图不会因为文本长度变化而出现重叠或截断的情况。对于RTL语言,要确保布局方向正确。
  3. 日期和数字格式测试:在不同地区设置下测试日期和数字的格式化,确保格式符合当地习惯。
  4. 图像测试:检查不同语言版本的图像是否正确加载和显示。

通过全面的本地化测试,可以提高应用在全球范围内的用户体验。

总结Swift本地化与国际化要点

在Swift开发中,实现本地化和国际化需要综合运用多种技术和工具。从字符串的本地化,到日期、数字格式的适配,再到图像、布局和RTL语言的处理,每个环节都至关重要。通过遵循上述步骤和方法,并进行充分的测试,可以打造出一个能够满足全球用户需求的高质量应用。同时,动态本地化功能为用户提供了更加灵活的语言切换体验,进一步提升了应用的可用性。在实际开发中,要根据项目的需求和目标用户群体,精心设计和优化本地化与国际化方案,以确保应用在全球市场上的成功。