Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application language change issue #74

Open
judithgomezlorenzo opened this issue Jul 30, 2024 · 11 comments
Open

Application language change issue #74

judithgomezlorenzo opened this issue Jul 30, 2024 · 11 comments
Assignees

Comments

@judithgomezlorenzo
Copy link

Hi,

We have a problem with Phrase.localizedString or OTA.

Context

  • Version : 4.4.1
  • We are pulling translations offline to embed them in Localizable.strings files.
  • OTA is in place with an updateTranslation at app launch.
  • PhraseSDKMainBundleProxyDisabled is set to YES in Info.plist
  • We have 8 different languages

Result

  • If we use Phrase.localizedString and change the app language from English to FR or DE, the app will still be in English (which is the default locale).
  • If we use NSLocalizedString, the app can change the locale, but then we do not get any update from OTA.

Could you help us? Thanks in advance.

@carstenapploft carstenapploft self-assigned this Jul 31, 2024
@carstenapploft
Copy link
Collaborator

Hi,
I need some more information about the language change process.

Do you change the language in the Apple Settings or do you use another method?

Can you describe this in a more detail?

@judithgomezlorenzo
Copy link
Author

Hello,

Inside our app we have direct access to the Apple settings to change the language.
We support English (US, CA, UK), French, German and Spanish.

To give you more details:

  • Using Phrase.localizedString: if the app language is changed to anything other than EN, the app will remain in English instead of changing to the language selected in Apple Settings, but then the OTA service will work as expected.
  • Using NSLocalizedString: if the app language is changed, then the app is shown in the selected language, but OTA doesn't work, the strings are not updated after changing in Phrase and uploading a new version.

I hope this explanation has enough detail for you.

Thank you,

@carstenapploft
Copy link
Collaborator

Hi @judithgomezlorenzo ,

sorry for the late response(another task required more time).

Do you use english default values in the calls to Phrase.shared.localizedString?
It is possible that the defaults will be returned as long as we download the translations.

Example:
Phrase.shared.localizedString(forKey: "your_translation_key", value: "the_english_text_as_fallback", table: "Localizable")

The order in which we determine the translation is as follows:

  1. OTA translation, if the files are loaded from the OTA server
  2. fallback text(value)
  3. if no fallback is available, we use the original translations from the app bundle.

That can explain why the translations are always in English after a language change.

And why NSLocalizedString works, maybe you have disabled "PhraseSDKMainBundleProxyDisabled" in the Info.plist? In this case, NSLocalizedString always returns the translations from the app bundle.

One more question about changing the language. You said you have direct access to the Apple settings to change the language. But you didn't mean the UserDefauls, right?

The app is restarted after changing the language?

@judithgomezlorenzo
Copy link
Author

Hi @carstenapploft,

No worries.
The app is restarted after changing the language, we do it through Apple settings, not User Defaults.
The PhraseSDKMainBundleProxyDisabled key is set to YES.

We don't use english default values when calling Phrase.shared.localizedString, we have an extension to localise any string like:

func localized() -> String {
    return Phrase.shared.localizedString(forKey: self, value: nil, table: nil)
}

We call Phrase.shared.updateTranslation inside the AppDelegate on app launch and we also try to override the locale with Phrase.shared.configuration.localeOverride but without luck.

@carstenapploft
Copy link
Collaborator

hi,

there is a case where we fall back to the "Base.lproj" translations if no bundle could be created for the selected language. Can you check whether this code returns a valid URL in the app and whether the url is also a directory?

extension URL {
   var isDirectory: Bool {
     (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
   }
}
// inside your app(e.g. AppDelegate)
let languageCode: String = Bundle.main.preferredLocalizations.first!
        
let modifiedLanguageCode = languageCode.replacingOccurrences(of: "_", with: "-")
let languageURL = Bundle.main.url(forResource: modifiedLanguageCode, withExtension: "lproj")

print(languageURL)
print(languageURL?.isDirectory)

@judithgomezlorenzo
Copy link
Author

Hello,

After running the above piece of code:

  • Simulator:
Optional(file:///Users/judith/Library/Developer/CoreSimulator/Devices/59D49403-21E3-49EE-9639-9EC6AEC38359/data/Containers/Bundle/Application/ECC48499-0152-49B3-BF91-B972CDD4E3B0/x.app/en-GB.lproj/)
Optional(true)
  • Real device
Optional(file:///private/var/containers/Bundle/Application/BEF9FCCA-2DC5-4E4A-9C8A-57AD4BD48D08/x.app/en-GB.lproj/)
Optional(true)

@carstenapploft
Copy link
Collaborator

Hello @judithgomezlorenzo ,
thanks for trying. I still assume there is a problem with pulling the fallback translations from the app bundle.
Can you also run the code once after you have changed the language? (e.g. from English to German).

Can you tell me if the translations are also in English after you change the language between non-English languages? (e.g. from German to French)

If I'm right and the problem is in the fallback translation and you say NSLocalizedString works, then you can specify NSLocalizedString as a fallback and it should work(as a workaround).

func localized() -> String {
    return Phrase.shared.localizedString(
        forKey: self,
        value: NSLocalizedString(self, comment: ""),
        table: nil
    )
}

@judithgomezlorenzo
Copy link
Author

Hi @carstenapploft,

Sorry for the late reply, I have been out of town these days.
If I change the localized method as you suggested, when I change the language from English to German, then the app seems to restart in German, but once the LaunchScreen is dismissed, the app is translated back to English.

If I switch from German to French, the same thing happens, the LaunchScreen is in French, but then the app is in English.

@carstenapploft
Copy link
Collaborator

Hi @judithgomezlorenzo ,
too bad that this did not work out. I had been trying to recreate the problem for the last few days, but without success.

We should check the API calls that are sent from SDK. Maybe the server always returns English translations.
Please use Charles (or a similar tool) to check whether the correct translation are returned.

The first URL should look like this(this will redirect to the second url):
https://ota.eu.phrase.com/<id>/<secret>/en/strings?client=iOS&platform_version=<iosVersion>&sdk_version=4.4.1&app_version=1.0.0&device_identifier=<id>

And the second url should look like this and contains the translations:
https://cdn.phraseapp.com/ota/<id>/strings/en.strings?version=<number>
(You may need to delete the app beforehand so that the cache is removed)

Please do not post your URLs here as they contain api secrets.
I will be away next week and be back on 16 September.

You can also submit a bug report here(This allows us to assign the problem to an organization.):
https://support.phrase.com/hc/en-us/requests/new

@judithgomezlorenzo
Copy link
Author

Hi @carstenapploft,

I've checked the API calls through Charles and the URLs look like:
The first one:
https://ota.eu.phrase.com/.../.../es/strings?client=iOS&platform_version=17.6.1&sdk_version=4.4.1&app_version=4.1.0&device_identifier=...

And then:
https://cdn.phraseapp.com/ota/.../.../stringsdict/en-US.stringsdict?version=130

Do you prefer me to submit a bug report?

Thanks!

@carstenapploft
Copy link
Collaborator

hi @judithgomezlorenzo ,

it looks like the API delivers the standard translation(en-US). This can happen if the language was not found or the language is not part of the OTA distribution.

You can check in the Phrase Dashboard under ‘Over the Air’ -> {your_distribution_name} -> gearwheel/settings whether all languages are selected for the distribution. If not, select all and create a new release with all languages.

If the problem persists after that, please create a bug report so that my colleagues can take a look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants