9 Replies
      Latest reply on Mar 10, 2020 1:54 PM by Claude31
      Viktor Yurchuk Level 1 Level 1 (0 points)

        Please tell me maybe you know how to do this. It is necessary to programmatically change the selected location. In iOS 13, you can select it in the settings. Interestingly, you can change in a local language change (if you changed the localization in the application) immediately.

        • Re: Change the language of iOS 13
          Claude31 Level 8 Level 8 (9,145 points)

          Could you clarify what is your question ?

            • Re: Change the language of iOS 13
              Viktor Yurchuk Level 1 Level 1 (0 points)

              the user changes the language of the application in the application, it is necessary that it changes in the application settings.

              https://www.icloud.com/iclouddrive/0K1YrvSJwpcjhXcCnpO66Jf1w#IMG_0074

              This choice needs to be changed from the application.

                • Re: Change the language of iOS 13
                  Claude31 Level 8 Level 8 (9,145 points)

                  OK, so that is not a question but a request for change.

                   

                  You'd better file a bug report for enhancement (this has been done by others, but you should request and explain as well).

                   

                  I do agree, it is a pain that it is not possible to do it in app ; there are cases where that would be much needed.

                  Note: you can do it in fact, but you have to manage the localization yourself, which is not very hard, but not convenient ; in fact, this is needed if you want to localize in a language that is not supported.

                    • Re: Change the language of iOS 13
                      Viktor Yurchuk Level 1 Level 1 (0 points)

                      Is it not possible to change the selected language?

                        • Re: Change the language of iOS 13
                          Claude31 Level 8 Level 8 (9,145 points)

                          Not possible with authorized API.

                            • Re: Change the language of iOS 13
                              Viktor Yurchuk Level 1 Level 1 (0 points)

                              there is an application that can change the language in the settings

                                • Re: Change the language of iOS 13
                                  Claude31 Level 8 Level 8 (9,145 points)

                                  Yes it is technically possible, but you should be warned that it may have side effects. The safe way is to do it yourself. I did it in one app.

                                   

                                  May also have a look at this old threads.

                                  https://forums.developer.apple.com/message/95091#95091

                                  https://forums.developer.apple.com/message/335094#335094

                                  https://forums.developer.apple.com/thread/97110

                                   

                                  I did file a bug report, 2 years ago, with the following content:

                                  FB5433678 (37636544)

                                  Here is the use case : Working with a foreign friend, it may be needed to change the language on the fly, each time one or the other has to do something with the app.

                                  There is no easy or safe way to do this directly from the app without being forced to go through the phone setting, which forces to interrupt use of app and takes a long time (up to 15s).

                                  I have found ways on how to do it, by changing the mainBundle class.

                                  See: h ttp://blog.xebia.fr/2016/08/03/internationaliser-vos-applications-ios/

                                  It seems to work well, but I was advised not to do so, because of possible bad side effects.

                                  See discussion in forum : https://forums.developer.apple.com/thread/97110

                                    • Re: Change the language of iOS 13
                                      Viktor Yurchuk Level 1 Level 1 (0 points)

                                      Tell me how you did it?

                                       

                                      https://www.icloud.com/iclouddrive/0gCoW3CtjbW4hrLo7XvNrMVZw#RPReplay_Final1583649661

                                       

                                      solution

                                       

                                      UserDefaults.standard.set(["en"], forKey: "AppleLanguages")

                                        • Re: Change the language of iOS 13
                                          Claude31 Level 8 Level 8 (9,145 points)

                                          Here is how I did it. It is a bit complex (that's why localization is so interesting)

                                           

                                          I localize separately items that are defined statically in IB and those defined dynamically in code (somehow in the same way it is done with Main.strings and localizable.strings)

                                           

                                          I created an enum, with a computed property dictionary traductions, which returns, for a given language, the localized string of each IB element when it is static text.

                                           

                                          I copy the IB item Object ID into its restoration ID, for every object.

                                           

                                          enum Language: String {
                                              case french = "fr-FR"
                                              case english = "en-US"
                                              case italian = "it-IT"
                                              case spanish = "es-ES"
                                          
                                              static let allLanguages = [french, english, italian, spanish]
                                          
                                              var traductions: [String:String] {
                                                  var trados = [String:String]()
                                                  switch self {
                                                  case .french :
                                                      trados["xle-Bf-Akb"] = "texte en français"
                                                      // many more like this
                                                  case .english :
                                                      trados["xle-Bf-Akb"] = "text in english"
                                                      // many more like this
                                                  case .italian :
                                                      trados["xle-Bf-Akb"] = "testo in italiano"
                                                      // many more like this
                                                  case .spanish :
                                                      trados["xle-Bf-Akb"] = "texto en español"
                                                      // many more like this
                                                    }
                                                  return trados
                                              }
                                          }

                                           

                                          I declared a global for dynamic texts:

                                           

                                          var textesTraduits = [String: [Language:String]] ()  // Dynamic texts: translation of each field (by its restoration ID) in each language

                                          Now this is done in each VC.

                                          In the code, each time I define a dynamic string for some object, I populate textesTraduits

                                           

                                              @IBAction func numericEntered(_ sender: UITextField) {     // I validate a text field ; I could have to set several items on display, just show for one
                                          
                                                  var allTexts = [Language:String]()
                                                  textesTraduits["VI0-db-g0w"] = allTexts // empty, a priori for this given ID
                                                    // Here is for a label with restoration ID of "6XA-e2-fHz"
                                                      allTexts[.french] = "Pas un chiffre"
                                                      allTexts[.english] = "Not a number"
                                                      allTexts[.italian] = "Non un numero"
                                                      allTexts[.spanish] = "No un numero"
                                                      errorLabel.text = allTexts[gSelectedLanguage]
                                                      textesTraduits["6XA-e2-fHz"] = allTexts     // That will be used when I toggle language later
                                          }

                                          I set the language via a segmentedControl and store the selection in a global var

                                           

                                          var gSelectedLanguage : Language = .french // To start with

                                           

                                           

                                          Now, in each VC, I call this func on viewWillAppear (I could also call it if notified that language has changed, but in my case I didn't need it)

                                          I call similar code when I change the segmentedControl, as well as in viewDidLoad in the VC that contains this control.

                                           

                                              func setLanguage() {
                                                 
                                                  let allViews = self.view.getAllSubviews()
                                                  for sub in allViews { 
                                                      if let label = sub as? UILabel, let id = sub.restorationIdentifier {
                                                          // Static messages are in Languages enum
                                                          if let traduit = gSelectedLanguage.traductions[id] {
                                                              label.text = traduit
                                                          } else if let traduit = textesTraduits[id] {
                                                              //  Translate dynamic message referenced by restoration ID
                                                              label.text = traduit[gSelectedLanguage]
                                                          }
                                                      }
                                                      // for textFields, 
                                                          if let textView = sub as? UITextField, let id = sub.restorationIdentifier {
                                                              if let traduit = textesTraduits[id], !traduit.isEmpty { 
                                                                  textView.text = traduit[gSelectedLanguage]
                                                              }
                                                          }
                                                     
                                                      if let button = sub as? UIButton, let id = sub.restorationIdentifier {
                                                          if let traduit = gSelectedLanguage.traductions[id] {
                                                              button.setTitle(traduit, for: .normal)
                                                          } else if let traduit = textesTraduits[id] {
                                                              button.setTitle(traduit[gSelectedLanguage], for: .normal)
                                                          }
                                                      }
                                                      if let textView = sub as? UITextView, let id = sub.restorationIdentifier {
                                                          if let traduit = gSelectedLanguage.traductions[id] {
                                                              textView.text = traduit
                                                          } else if let traduit = textesTraduits[id] {
                                                              textView.text = traduit[gSelectedLanguage]
                                                          }
                                                      }
                                                  }
                                                  // For a button that was created in code, we don't have the restoration ID
                                                  var buttonName = "↵"
                                                  switch gSelectedLanguage {
                                                  case .french : buttonName = "retour"
                                                  case .english: buttonName = "done"  
                                                  case .italian: buttonName = "invio"  
                                                  case .spanish: buttonName = "entrar"
                                                  }
                                                  returnButton.setTitle(buttonName, for: UIControl.State())
                                              }

                                           

                                           

                                          I told you it was a bit complex (probably can be simplified a bit, but it works well). I can even add languages that are not listed in the languages supported by iOS.

                                           

                                          Some caveat: the app does not localize when you change the iPhone setting, unless you restart the app. But that's what we wanted, isn't it ?  And if you have selected italian in app when iPhone setting is english, the apps settings in General settings will be english, not italian.

                                           

                                          with this mechanism, you can switch language on the fly, for instance when you rotate the device of flip form portrait up to protrait down… Pretty cool.