Reputation: 19869
We are building an application with dynamic data that we wish to localize. We know how to localize strings in iOS and Android but in this case the data will be downloaded dynamically from the server so we will need to download the localization files dynamically.
Usually we store the strings files inside language folders. how can we do that when the file is coming from the server?
Upvotes: 18
Views: 6190
Reputation: 3535
Looking at the Apple documentation for Text: https://developer.apple.com/documentation/swiftui/text
The SwiftUI text view initializer accepts a bundle
parameter.
1 - We need to create a custom bundle. This can be done using the convenience initializer with a URL to our custom bundle:
convenience init?(url: URL)
https://developer.apple.com/documentation/foundation/bundle/1409352-init
2 - place programmatically the language folders in it ( and add the strings files inside).
The languages available on device can be found in:
Bundle.main.localizations
. which returns an array such as:
["de", "en", "Base", "en-US", "de-DE"]
You need to take this array and create the corresponding folders "de.proj", "en.proj" etc. in your custom bundle.
Then add the .strings
files with the key - translated value pairs such as ex in en.proj
the assets.strings
with:
`"Titlekey54" = "Localised title English";
This will show "Localised title English" in your UI if you selected English in settings and you passed the correct bundle to the Text
initializer.
NB: If you pass a variable you need to pass a LocalizedStringKey type or it will not localise automatically
(from the apple docs)
// a string variable will not be localized
Text(writingImplement)
// ...unless you explicitly convert it to a localized string key.
Text(LocalizedStringKey(writingImplement))
In this case I created a class to hold the current custom bundle and a setter to change it when the user changes language in the app.
The code to create the directories is a bit complicated and I don't want to make this post too long. I will try to make my code available later on.
I made it to work in this small prototype app:
https://github.com/multitudes/MyLocalisationTestApp
Also, to create custom bundles on disk I found some good resource in this repo. 👍🏻 https://github.com/bharathi91/NextLevelLocalization
Upvotes: 0
Reputation: 105
What our company was thinking about is to send the language of the device and the last time the language was updated to the server. Then, the server checks the language in the database, and if the language exists, it sends, if not, it will send english list of translations by default. The response consists of the list of array of key: value data, and the last time it was updated, which is sent every time the app launches. So mobile should cache the list of translations, and just use the data from cache. In this case you do not need to use xml file of localized, and since the server is checking the last time it was updated, you do not have to refresh the key value data everytime, but only the data which you for from the server.
Upvotes: 0
Reputation: 641
Yes, it's possible, but not using standard means. Check this github repository for simple and elegant solution.
It uses .json file which contains localization info and may be downloaded from server. All controllers need to subscribe to notifications sent by localization class and implement a method responsible for (re-)setting all texts in view.
Upvotes: 3
Reputation: 135548
how can we do that when the file is coming from the server?
You can't because the app bundle is not writable on iOS devices.
There is, however, NSLocalizedStringFromTableInBundle()
, which lets you specify a different bundle from which you can load the .strings
file. I haven't tried but I suppose this bundle can also reside in your app's Documents or Library folder.
Upvotes: 12