Hi, I just wanted to know what would be a good way to deal with localizations. I would like to control them with the environment, but that means having to trigger an action and then receiving the localized texts. For the first view I would require some initial state that just displays nothing, and then wait for the texts to come, then transition to the first real view. I'm thinking it might get cumbersome to do this for each view. Ideas?
Hi @Jose_Manuel_Sanchez,
can’t you use iOS’s localization capabilities and localize based on the users settings (which iOS automatically takes care of)?
Is there any reason why you would want to go this particular route? What are you trying to control?
@slashmo's suggestion seems the most sensible
Having the localization function in the environment is very useful. This is something I've done with a global environment, and it gives me the ability to set a specific language for debugging, have double, triple strings for checking very long texts, update the localizations from a server, etc. I could just have a global function, but it's actually reading from files, this is an effect. If you want to test that your final strings are correct, for example, how are you going to do that if you don't control this effect?
This is probably not relevant to what you’re trying to achieve but the way I handle localization in my app is by using LocalizedStringKey that comes with Text where you simply pass a key in the Text initializer such as Text("some_title"). It will look up for this key in the Localizable.strings file and replace it with the translation.
To fit with TCA, I have a Translation framework with the Localizable.strings files and an empty class to use with Bundle(for:). I actually have a SwiftUI component that uses Text(_:bundle:) so I don’t need to import Translation everywhere but rather use this custom component that I called BundleLocalizedText. It works in the Simulator and the Swift Previews so that’s enough in my case.
But with this approach, I cannot unit test that my strings are correct but I use different locales in multiple Swift Previews to see how it behaves.
Hope that helps.
Have you considered a high order reducer? The 04-HigherOrderReducers-ReusableFavoriting Example seems appropriate. You could use that to manage just the Effects from your localization logic.
You could then maybe use a global state that holds your localizations and have a System Environment to drill down to. The 03-Effects-SystemEnvironment.swift use case also seems appropriate.
I'm curious, how many times do you update localizations from a server?
Are you trying to test your strings output as they arrive from your service, or the state change that happens in your TCA architecture?
Thanks for the help! I realized that I don't really need to return an effect if it's synchronous. They already do this for UUIDs, where they just call the environment function which directly returns the new id, no need to return the effect and add another action. I think I will just add the strings in the state, and have some initial actions so they are translated before being presented.