优化多语言文本加载性能(尤其是应用启动时)
- 预加载:在应用启动时,提前加载最常用语言的本地化文件。可以使用
DispatchQueue.global(qos: .userInitiated).async
开启异步线程进行加载,避免阻塞主线程。例如:
DispatchQueue.global(qos: .userInitiated).async {
let bundle = Bundle(for: type(of: self))
let path = bundle.path(forResource: "Localizable", ofType: "strings", inDirectory: "en.lproj")
if let path = path {
let table = NSLocalizedStringTable("Localizable", path, nil)
// 这里可以对加载的本地化表做缓存等操作
}
}
- 缓存机制:创建一个缓存来存储已加载的本地化文本。使用
NSCache
或者自定义字典来实现。每次加载文本前先检查缓存中是否已有对应内容。
private let textCache = NSCache<NSString, NSString>()
func localizedString(key: String) -> String {
if let cachedString = textCache.object(forKey: key as NSString) {
return cachedString as String
}
let string = NSLocalizedString(key, comment: "")
textCache.setObject(string as NSString, forKey: key as NSString)
return string
}
- 优化本地化文件结构:将本地化文件按照模块或者功能进行拆分,只加载当前需要的部分。比如对于一个有用户模块和商品模块的应用,可以分别创建
UserLocalizable.strings
和 ProductLocalizable.strings
。
处理动态语言切换确保界面和数据无缝更新
- 通知机制:使用
NotificationCenter
监听语言切换通知,例如 NSApplicationDidChangeEffectiveAppearance
(在 macOS 上)或 NSCurrentLocaleDidChange
通知。当收到通知时,重新加载本地化文本并更新界面。
NotificationCenter.default.addObserver(self, selector: #selector(updateLocalization), name: NSCurrentLocaleDidChange, object: nil)
@objc func updateLocalization() {
// 重新加载本地化文本
label.text = NSLocalizedString("new_text_key", comment: "")
// 更新其他界面元素
}
- 数据一致性:对于动态数据,如从后端获取的文本,在语言切换时,要确保重新请求后端获取对应语言的数据。可以在请求头中添加语言标识,如
Accept-Language
字段。
let headers = [
"Accept-Language": Locale.current.languageCode ?? "en"
]
let request = NSMutableURLRequest(url: NSURL(string: "your_api_url")! as URL,
cachePolicy:.useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
- 视图控制器生命周期:在视图控制器的
viewWillAppear
方法中检查当前语言设置并更新界面,以确保每次视图显示时都是正确的语言。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
label.text = NSLocalizedString("updated_text_key", comment: "")
}
与后端服务交互时本地化与国际化相关陷阱及应对策略
- 语言标识不一致:
- 陷阱:前端设置的语言标识与后端期望的不一致,导致后端返回错误语言的数据。
- 策略:在项目初期,前后端明确统一的语言标识格式,如 ISO 639 - 1 标准(如 "en" 代表英语,"zh" 代表中文)。并且在每次请求和响应中添加日志记录语言标识,便于排查问题。
- 日期和数字格式:
- 陷阱:不同地区的日期和数字格式不同,后端返回的数据格式可能与前端显示要求不匹配。例如,美国日期格式是 "MM/dd/yyyy",而欧洲一些国家是 "dd/MM/yyyy"。
- 策略:前端在显示日期和数字时,使用
DateFormatter
和 NumberFormatter
并根据当前用户地区设置进行格式化。后端在存储和传输数据时,建议使用标准格式(如 ISO 8601 日期格式),前端收到数据后再进行本地格式转换。
- 字符编码问题:
- 陷阱:不同语言的字符集不同,如果后端和前端之间字符编码不一致,可能导致乱码。
- 策略:统一使用 UTF - 8 编码进行数据传输和存储,这是目前广泛支持且能处理大多数语言字符的编码格式。同时,在网络请求和响应处理中设置正确的编码格式,如在
NSURLRequest
中设置 HTTPBody
的编码为 UTF - 8。