Lingo logo

swift 5 MIT License

特性设置用法性能许可证

Lingo 是一个纯 Swift 本地化库,可以用于服务器端 Swift 项目,但不仅限于这些项目。

特性

设置

集成 Lingo 有两种方式,具体取决于您是否使用 Vapor

使用 Vapor

如果您正在使用 Vapor,我们建议您使用 LingoProvider,它将提供与 Vapor 的无缝和原生集成。这样,Lingo 成为 Droplet 的一部分,您将能够更轻松地获取本地化内容

let localizedTitle = droplet.lingo.localize("welcome.title", locale: "en")

LingoProvider 是一个独立的软件包,可以从 GitHub 下载。如果您使用 LingoProvider,则不需要 Lingo 软件包依赖项。

不使用 Vapor

添加依赖项

dependencies: [
	...,
	.Package(url: "https://github.com/miroslavkovac/Lingo.git", majorVersion: 4)
]

创建 Lingo 对象的实例,并传入本地化文件所在的根目录路径

let lingo = try Lingo(rootPath: "path/to/localizations", defaultLocale: "en")

从版本 3 升级到版本 4

在版本 4 中,区域设置标识符的格式已更改为与 RFC 5646 匹配。版本 3 使用 _ 分隔语言代码国家/地区代码,而现在版本 4 使用 -

如果您使用了任何包含国家/地区代码的区域设置,则需要重命名相关的翻译文件以匹配新格式。

用法

使用以下语法在 JSON 文件中定义本地化内容

{
	"title": "Hello Swift!",
	"greeting.message": "Hi %{full-name}!",
	"unread.messages": {
		"one": "You have an unread message.",
		"other": "You have %{count} unread messages."
	}
}

请注意,此语法与 i18n-node-2 兼容。如果您正在使用第三方本地化服务,该服务将为您导出本地化文件,这将非常有用。

本地化

您可以像这样检索本地化字符串

let localizedTitle = lingo.localize("title", locale: "en")

print(localizedTitle) // will print: "Hello Swift!"

字符串插值

您可以像这样插值本地化字符串

let greeting = lingo.localize("greeting.message", locale: "en", interpolations: ["full-name": "John"])

print(greeting) // will print: "Hi John!"

复数化

Lingo 支持 CLDR 中定义的所有 Unicode 复数类别

示例

let unread1 = lingo.localize("unread.messages", locale: "en", interpolations: ["count": 1])
let unread24 = lingo.localize("unread.messages", locale: "en", interpolations: ["count": 24]) 

print(unread1) // Will print: "You have an unread message."
print(unread24) // Will print: "You have 24 unread messages."

每种语言都包含自定义的复数化规则,这些规则定义了哪个数字值应使用哪个复数类别。Lingo 目前实现了以下语言的规则

ak, am, ar, az, be, bg, bm, bn, bo, br, bs, ca, cs, cy, da, de-AT, de-CH, de-DE, de, dz, el, en-AU, en-CA, en-GB, en-IN, en-NZ, en, eo, es-419, es-AR, es-CL, es-CO, es-CR, es-EC, es-ES, es-MX, es-NI, es-PA, es-PE, es-US, es-VE, es, et, eu, fa, ff, fi, fil, fr-CA, fr-CH, fr-FR, fr, ga, gd, gl, gv, he, hi-IN, hi, hr, hsb, hu, id, ig, ii, it-CH, it, iu, ja, jv, ka, kab, kde, kea, km, kn, ko, ksh, kw, lag, ln, lo, lt, lv, mg, mk, ml, mn, mr-IN, ms, mt, my, naq, nb, ne, nl, nn, nso, or, pa, pl, pt, pt-BR, ro, ru, sah, se, ses, sg, shi, sk, sl, smn, sr, sv-SE, sv, sw, th, ti, to, tr, tzm, uk, ur, vi, wa, wo, yo, zh-CN, zh-HK, zh-TW, zh

复数化规则的原始种子是从 Rails i18n 翻译成 Swift 的。

性能

在包含 1000 个本地化键(包括复数形式)的集合的测试中,该库能够处理

字符串插值在底层使用正则表达式,这可以解释性能差异。所有测试均在 i7 4GHz CPU 上执行。

自定义本地化数据源

尽管大多数情况下,本地化内容将在 JSON 文件中定义,但如果您更喜欢将其保存在数据库中,我们也能满足您的需求!

要实现自定义数据源,您只需要一个符合 LocalizationDataSource 协议的对象

public protocol LocalizationDataSource {   

    func availableLocales() throws -> [LocaleIdentifier]
    func localizations(forLocale: LocaleIdentifier) throws -> [LocalizationKey: Localization]
    
}

因此,假设您正在使用 MongoDB 存储您的本地化内容,您需要做的就是创建一个数据源并将其传递给 Lingo 的指定初始化器

let mongoDataSource = MongoLocalizationDataSource(...)
let lingo = try Lingo(dataSource: mongoDataSource, defaultLocale: "en")

Lingo 已经包含符合此协议的 FileDataSource,正如您可能猜到的,它与带有 rootPath 的 Longo 的便捷初始化器连接在一起。

关于区域设置标识符的说明

虽然区域设置的命名方式完全取决于您,但有一种简单的方法可以直接从 Locale 类获取所有区域设置的列表

import Foundation

print(Locale.availableIdentifiers)

在添加对新区域设置的支持时,请记住这一点。

限制

目前,该库不支持在同一本地化字符串的不同部分应用不同复数类别的情况。例如,给定以下定义

{
    "key": {
        "one": "You have 1 apple and 1 orange.",
        "other": "You have %{apples-count} apples and %{oranges-count} oranges."
    }
}

并传递数字 1 和 7

print(lingo.localize("key", locale: "en", interpolations: ["apples-count": 1, "oranges-count": 7]))

将打印

You have 1 apple and 7 orange.

请注意打印的消息中缺少 s

这是有意为之,这样做的原因是保持 JSON 文件语法的简单和优雅(与 iOS .stringsdict 文件和类似文件形成对比)。如果您仍然需要支持这种情况,一种可能的解决方法是将该字符串拆分为两个,然后在代码中稍后组合它们。

进一步的工作

许可证

MIT 许可证。请参阅包含的 LICENSE 文件。