我们正在使用我们希望本地化的动态数据构建一个应用程序。我们知道如何在 iOS 和 Android 中本地化字符串,但在这种情况下,数据将从服务器动态下载,因此我们需要动态下载本地化文件。
通常我们将字符串文件存储在语言文件夹中。当文件来自服务器时,我们怎么能做到这一点?
我们正在使用我们希望本地化的动态数据构建一个应用程序。我们知道如何在 iOS 和 Android 中本地化字符串,但在这种情况下,数据将从服务器动态下载,因此我们需要动态下载本地化文件。
通常我们将字符串文件存储在语言文件夹中。当文件来自服务器时,我们怎么能做到这一点?
当文件来自服务器时,我们怎么能做到这一点?
你不能因为 app bundle 在 iOS 设备上是不可写的。
但是,有NSLocalizedStringFromTableInBundle()
,它允许您指定一个不同的包,您可以从中加载.strings
文件。我还没有尝试过,但我想这个包也可以驻留在您的应用程序的 Documents 或 Library 文件夹中。
是的,这是可能的,但不使用标准方法。检查这个 github 存储库以获得简单而优雅的解决方案。
它使用包含本地化信息的 .json 文件,可以从服务器下载。所有控制器都需要订阅本地化类发送的通知,并实现一个负责(重新)设置视图中所有文本的方法。
查看文本的 Apple 文档: https ://developer.apple.com/documentation/swiftui/text
SwiftUI 文本视图初始化程序接受一个bundle
参数。
1 - 我们需要创建一个自定义包。这可以使用带有指向我们自定义包的 URL 的便捷初始化程序来完成:
convenience init?(url: URL)
https ://developer.apple.com/documentation/foundation/bundle/1409352-init
2 - 以编程方式将语言文件夹放入其中(并在其中添加字符串文件)。
设备上可用的语言可在以下位置找到:
Bundle.main.localizations
。它返回一个数组,例如:
["de", "en", "Base", "en-US", "de-DE"]
您需要获取此数组并在自定义包中创建相应的文件夹“de.proj”、“en.proj”等。
然后在 with 中添加带有键翻译值对的文件.strings
,例如 ex :
`"Titlekey54" = "Localised title English";en.proj
assets.strings
如果您在设置中选择了英语并将正确的捆绑包传递给Text
初始化程序,这将在您的 UI 中显示“本地化标题英语”。
注意:如果你传递一个变量,你需要传递一个 LocalizedStringKey 类型,否则它不会自动本地化
(来自苹果文档)
// a string variable will not be localized
Text(writingImplement)
// ...unless you explicitly convert it to a localized string key.
Text(LocalizedStringKey(writingImplement))
在这种情况下,我创建了一个类来保存当前的自定义包和一个设置器来在用户更改应用程序中的语言时更改它。
创建目录的代码有点复杂,我不想让这篇文章太长。稍后我将尝试使我的代码可用。
我让它在这个小型原型应用程序中工作:
https ://github.com/multitudes/MyLocalisationTestApp
此外,为了在磁盘上创建自定义包,我在这个 repo 中找到了一些很好的资源。 https://github.com/bharathi91/NextLevelLocalization
我们公司考虑的是将设备的语言和上次更新语言的时间发送到服务器。然后,服务器检查数据库中的语言,如果该语言存在,则发送,如果不存在,则默认发送英文翻译列表。响应由 key: value 数据数组的列表和上次更新时间组成,每次应用启动时都会发送。所以移动端应该缓存翻译列表,并且只使用缓存中的数据。在这种情况下,您不需要使用本地化的 xml 文件,并且由于服务器正在检查上次更新的时间,因此您不必每次都刷新键值数据,而只需刷新您从服务器获取的数据。