Multilingual app without localizing

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I'm making an iOS app which supports multiple languages but not in the built-in localized way. In iOS, for localization to work, the user has to change the device's language. But in the app I'm working on, the user needs to be able to choose the language to effect only this app. So for example, I can have the device's language set to English but the user can choose Spanish to be set as the language within the app.



I took some concepts from iOS localization and added some things on my own. First I created plists to contain strings for each language I support.



English



enter image description here



Spanish



enter image description here



Next I created a singleton which handles the setting on the chosen language and serving the strings based on that selected language. I use a third-party library called SwiftyPlist for easier manipulation of plists.



enum Language: String 
case english = "en"
case spanish = "es"


class LanguageManager
static let shared = LanguageManager()

private var plist: Plist!

// Get/Set the language of choice
var language: Language?
set
UserDefaults.standard.set(newValue?.rawValue, forKey: "Language")
reloadPlist()

get
if let code = UserDefaults.standard.object(forKey: "Language") as? String
return Language(rawValue: code)
else
return nil





private init()
reloadPlist()


// Reload the corresponding plist
private func reloadPlist()

var name: String
return plist["YOUR_NAME"]!.string!





Now I can set the chosen language like this.



LanguageManager.shared.language = .spanish


And I can simply access the strings like so.



LanguageManager.shared.name


I feel like this is a good, scalable approach to my requirement. But I'd like to see if it has room to improvement.



Demo project







share|improve this question

























    up vote
    3
    down vote

    favorite












    I'm making an iOS app which supports multiple languages but not in the built-in localized way. In iOS, for localization to work, the user has to change the device's language. But in the app I'm working on, the user needs to be able to choose the language to effect only this app. So for example, I can have the device's language set to English but the user can choose Spanish to be set as the language within the app.



    I took some concepts from iOS localization and added some things on my own. First I created plists to contain strings for each language I support.



    English



    enter image description here



    Spanish



    enter image description here



    Next I created a singleton which handles the setting on the chosen language and serving the strings based on that selected language. I use a third-party library called SwiftyPlist for easier manipulation of plists.



    enum Language: String 
    case english = "en"
    case spanish = "es"


    class LanguageManager
    static let shared = LanguageManager()

    private var plist: Plist!

    // Get/Set the language of choice
    var language: Language?
    set
    UserDefaults.standard.set(newValue?.rawValue, forKey: "Language")
    reloadPlist()

    get
    if let code = UserDefaults.standard.object(forKey: "Language") as? String
    return Language(rawValue: code)
    else
    return nil





    private init()
    reloadPlist()


    // Reload the corresponding plist
    private func reloadPlist()

    var name: String
    return plist["YOUR_NAME"]!.string!





    Now I can set the chosen language like this.



    LanguageManager.shared.language = .spanish


    And I can simply access the strings like so.



    LanguageManager.shared.name


    I feel like this is a good, scalable approach to my requirement. But I'd like to see if it has room to improvement.



    Demo project







    share|improve this question





















      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I'm making an iOS app which supports multiple languages but not in the built-in localized way. In iOS, for localization to work, the user has to change the device's language. But in the app I'm working on, the user needs to be able to choose the language to effect only this app. So for example, I can have the device's language set to English but the user can choose Spanish to be set as the language within the app.



      I took some concepts from iOS localization and added some things on my own. First I created plists to contain strings for each language I support.



      English



      enter image description here



      Spanish



      enter image description here



      Next I created a singleton which handles the setting on the chosen language and serving the strings based on that selected language. I use a third-party library called SwiftyPlist for easier manipulation of plists.



      enum Language: String 
      case english = "en"
      case spanish = "es"


      class LanguageManager
      static let shared = LanguageManager()

      private var plist: Plist!

      // Get/Set the language of choice
      var language: Language?
      set
      UserDefaults.standard.set(newValue?.rawValue, forKey: "Language")
      reloadPlist()

      get
      if let code = UserDefaults.standard.object(forKey: "Language") as? String
      return Language(rawValue: code)
      else
      return nil





      private init()
      reloadPlist()


      // Reload the corresponding plist
      private func reloadPlist()

      var name: String
      return plist["YOUR_NAME"]!.string!





      Now I can set the chosen language like this.



      LanguageManager.shared.language = .spanish


      And I can simply access the strings like so.



      LanguageManager.shared.name


      I feel like this is a good, scalable approach to my requirement. But I'd like to see if it has room to improvement.



      Demo project







      share|improve this question











      I'm making an iOS app which supports multiple languages but not in the built-in localized way. In iOS, for localization to work, the user has to change the device's language. But in the app I'm working on, the user needs to be able to choose the language to effect only this app. So for example, I can have the device's language set to English but the user can choose Spanish to be set as the language within the app.



      I took some concepts from iOS localization and added some things on my own. First I created plists to contain strings for each language I support.



      English



      enter image description here



      Spanish



      enter image description here



      Next I created a singleton which handles the setting on the chosen language and serving the strings based on that selected language. I use a third-party library called SwiftyPlist for easier manipulation of plists.



      enum Language: String 
      case english = "en"
      case spanish = "es"


      class LanguageManager
      static let shared = LanguageManager()

      private var plist: Plist!

      // Get/Set the language of choice
      var language: Language?
      set
      UserDefaults.standard.set(newValue?.rawValue, forKey: "Language")
      reloadPlist()

      get
      if let code = UserDefaults.standard.object(forKey: "Language") as? String
      return Language(rawValue: code)
      else
      return nil





      private init()
      reloadPlist()


      // Reload the corresponding plist
      private func reloadPlist()

      var name: String
      return plist["YOUR_NAME"]!.string!





      Now I can set the chosen language like this.



      LanguageManager.shared.language = .spanish


      And I can simply access the strings like so.



      LanguageManager.shared.name


      I feel like this is a good, scalable approach to my requirement. But I'd like to see if it has room to improvement.



      Demo project









      share|improve this question










      share|improve this question




      share|improve this question









      asked Feb 25 at 11:12









      Isuru

      20239




      20239




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote













          I did something like this. You can also just use a Strings file. What I did was create a spreadsheet in the Google Drive with all the translations (one column for the identifier BUTTON_TITLE_OK and one each language the app supports). It's then very easy to make a little formula in Google Drive that takes all the identifiers, and turns it into an enum. Like so:



           enum LocalizedStringIdentifier: String 
          case BUTTON_TITLE_OK


          func string(_ identifier: LocalizedStringIdentifier) -> String?
          guard let value = plists[identifier.rawValue] else return nil
          return value



          The advantage of this that you get code completion in Xcode and thus less chance of mistakes. Usage:



          LanguageManager.shared.string(.BUTTON_TITLE_OK)


          The advantage of the spreadsheet approach is that you have all localizations combined so you have a better overview (and it is also easier to share with your client so that they can provide you with the right translations, unless this is your own project).



          Side note: If you do use plists, you should try use the new Codable protocol to load Plists directly into your models.






          share|improve this answer























            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188318%2fmultilingual-app-without-localizing%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote













            I did something like this. You can also just use a Strings file. What I did was create a spreadsheet in the Google Drive with all the translations (one column for the identifier BUTTON_TITLE_OK and one each language the app supports). It's then very easy to make a little formula in Google Drive that takes all the identifiers, and turns it into an enum. Like so:



             enum LocalizedStringIdentifier: String 
            case BUTTON_TITLE_OK


            func string(_ identifier: LocalizedStringIdentifier) -> String?
            guard let value = plists[identifier.rawValue] else return nil
            return value



            The advantage of this that you get code completion in Xcode and thus less chance of mistakes. Usage:



            LanguageManager.shared.string(.BUTTON_TITLE_OK)


            The advantage of the spreadsheet approach is that you have all localizations combined so you have a better overview (and it is also easier to share with your client so that they can provide you with the right translations, unless this is your own project).



            Side note: If you do use plists, you should try use the new Codable protocol to load Plists directly into your models.






            share|improve this answer



























              up vote
              3
              down vote













              I did something like this. You can also just use a Strings file. What I did was create a spreadsheet in the Google Drive with all the translations (one column for the identifier BUTTON_TITLE_OK and one each language the app supports). It's then very easy to make a little formula in Google Drive that takes all the identifiers, and turns it into an enum. Like so:



               enum LocalizedStringIdentifier: String 
              case BUTTON_TITLE_OK


              func string(_ identifier: LocalizedStringIdentifier) -> String?
              guard let value = plists[identifier.rawValue] else return nil
              return value



              The advantage of this that you get code completion in Xcode and thus less chance of mistakes. Usage:



              LanguageManager.shared.string(.BUTTON_TITLE_OK)


              The advantage of the spreadsheet approach is that you have all localizations combined so you have a better overview (and it is also easier to share with your client so that they can provide you with the right translations, unless this is your own project).



              Side note: If you do use plists, you should try use the new Codable protocol to load Plists directly into your models.






              share|improve this answer

























                up vote
                3
                down vote










                up vote
                3
                down vote









                I did something like this. You can also just use a Strings file. What I did was create a spreadsheet in the Google Drive with all the translations (one column for the identifier BUTTON_TITLE_OK and one each language the app supports). It's then very easy to make a little formula in Google Drive that takes all the identifiers, and turns it into an enum. Like so:



                 enum LocalizedStringIdentifier: String 
                case BUTTON_TITLE_OK


                func string(_ identifier: LocalizedStringIdentifier) -> String?
                guard let value = plists[identifier.rawValue] else return nil
                return value



                The advantage of this that you get code completion in Xcode and thus less chance of mistakes. Usage:



                LanguageManager.shared.string(.BUTTON_TITLE_OK)


                The advantage of the spreadsheet approach is that you have all localizations combined so you have a better overview (and it is also easier to share with your client so that they can provide you with the right translations, unless this is your own project).



                Side note: If you do use plists, you should try use the new Codable protocol to load Plists directly into your models.






                share|improve this answer















                I did something like this. You can also just use a Strings file. What I did was create a spreadsheet in the Google Drive with all the translations (one column for the identifier BUTTON_TITLE_OK and one each language the app supports). It's then very easy to make a little formula in Google Drive that takes all the identifiers, and turns it into an enum. Like so:



                 enum LocalizedStringIdentifier: String 
                case BUTTON_TITLE_OK


                func string(_ identifier: LocalizedStringIdentifier) -> String?
                guard let value = plists[identifier.rawValue] else return nil
                return value



                The advantage of this that you get code completion in Xcode and thus less chance of mistakes. Usage:



                LanguageManager.shared.string(.BUTTON_TITLE_OK)


                The advantage of the spreadsheet approach is that you have all localizations combined so you have a better overview (and it is also easier to share with your client so that they can provide you with the right translations, unless this is your own project).



                Side note: If you do use plists, you should try use the new Codable protocol to load Plists directly into your models.







                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited May 23 at 2:37


























                answered May 23 at 1:58









                Joris Weimar

                1314




                1314






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188318%2fmultilingual-app-without-localizing%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation