phrase / ios-sdk

Phrase Over the Air iOS SDK
https://phrase.com
Other
14 stars 3 forks source link

Application language change issue #74

Open judithgomezlorenzo opened 1 month ago

judithgomezlorenzo commented 1 month ago

Hi,

We have a problem with Phrase.localizedString or OTA.

Context

Result

Could you help us? Thanks in advance.

carstenapploft commented 1 month ago

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 commented 1 month ago

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:

Thank you,

carstenapploft commented 1 month ago

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 commented 3 weeks ago

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 commented 3 weeks ago

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 commented 3 weeks ago

Hello,

After running the above piece of code:

carstenapploft commented 3 weeks ago

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 commented 5 days ago

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 commented 2 days ago

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