So my main concern is being organized and doing it the right way. So I have a lot of strings in the app that I am working on. Some of the strings will be seen by the user but a lot of them are going to be internal to the app. So my question is how should I organize them all? I have been looking into NSLocalizedString which looks like a good offer but I just do not think that it makes sense to put all the strings that are not going to bee seen by the user into this file. What my understanding is, is that NSLocalizedString is made to create your app versatile for all languages. (Which I am still confused about how that works) and to reduce clutter, space etc. What I am currently thinking of doing is to put all the strings that will be seen by the user into the Localizable.strings file and all the other strings that are internal at the top of my files. Does this seem like the best practice? Am I missing anything? Any suggestions/tips would be a huge help.
Thank you prior for taking a minute to help a new developer. :)
I declare all my internal strings as constants in the implementation of my classes
NSString *const some_string = #"Some String";
that way they autocomplete so I am more confident with the type safety.
If I need them from another class you can also expose them in the header file of the class where they're defined.
extern NSString *const some_string;
For user visible strings that you want to later translate, localizable.strings is definitely the best place.
Related
I’ve been a procedural programmer for a long time and most of my iOS code is written with lots of if statements instead of sub-classing. I think I finally understand how to write object oriented code but I have a few questions.
I have a class, ScoringToolbar.m that is used in all of my games. It creates buttons for the bottom of the screen. Which buttons are created vary depending on the game and the options in the game. Here’s a typical screen.
Right now it is a long series of if statements. In addition to being hard to read, it’s definitely not proper object oriented programming. What I’d like to do is convert the class into a superclass and add a subclass for each game. My first question is: Is there a convention for naming the superclass?
Also, I’d like to keep the ScoringToolbar.m name for each of my sub-classes. If I create one sub-class for each of my apps (or group of similar apps) I can move the code from the if statements into it. Then each app would call its own subclass and create the buttons it needs. If I do that I won’t have to change any of the calling code. However, if I have lots of .m files with the same name, what do I do with the .h files. Do I have just one and make sure it works with all of the .m's. Or is there a way to tell Xcode to use a specific .h file in an app?
Or is this the wrong approach altogether?
I'm not sure subclassing is your best option. Your question about multiple .m files with the same name suggests this approach might get confusing. You might want to think of your ScoringToolbar as a control that your apps configure for their needs. In this way it wouldn't be much different than a UIButton. Each app would be responsible for creating an instance of the ScoringToolbar and setting it up to suit. It could do this in a method in an existing class or in a helper class. The ScoringToolbar takes care of rendering the UI (icons, colors) while the calling app indicates what options it needs (up/down votes, number correct/incorrect, etc).
I think subclassing is not a good option for you problem. You will end up with code which is hard to maintain and modify when your apps or no of apps grow big.
Have a look at some design patterns, if I got your problem correctly, builder pattern would be one of the options.
Or you can create configuration file for each game. For example you can have an array of dictionaries in a plist. Each dictionary will represent a UI element in the toolbar. For example you can store the image name, order, selector, position(?) and etc in the plist. When loading the application you can create the toolbar elements at run time using the dictionary options.
These are just a starting point but based on your requirements and extendability of your apps you can find better solutions.
I am still paying dearly for learning iOS development, so please be kind.
I have an iOS application containing around 400 NSString litterals. I never thought that I would want to localize this app later on, so while being aware of NSLocalizedString I decided to not use them for my project. Now the world has changed and I need to localize this application. Is there any tool/script I can use that will run through my .m files and "search/replace" my NSStrings with NSLocalizedStrings before I extract them with genstrings?
Thanks
Roger
You made a mistake not writing your code correctly the first time, and now you have to pay the price.
You need to go through your program manually and change user-visible string literals to calls to NSLocalizedString.
Note that you do NOT want to globally change all string literals. Things like dictionary keys should not be localized.
Always, ALWAYS, use NSLocalizedString to create localized strings. It's only a few more characters to type, and it makes internationalizing your code DRAMATICALLY easier.
The good news is that the pain of doing this will serve as a bitter lesson and you likely won't make the same mistake again.
Yes! A find and replace regex will speed up this up.
In the find bar put:
(".*")
In the replace bar:
NSLocalizedString($1,comment:"")
This will change "normalString" to NSLocalizedString("normalString",comment:"")
So go through your code and on the ones you want to replace just press replace, this is a massive timesaver!
You generally don't want to replace ALL NSStrings with NSLocalizedString as not all strings are necessarily 'user facing'. You might have string constants that are used internally that the user never sees and these in general should not be translated. Hence, blindly replacing all NSStrings with NSLocalizedString is probably not a great idea.
There is a fair bit of work involved going through and doing this manually, but its a one-time effort - once you've done it once you'll know the correct way to handle any new user-facing strings and do it as you go. Having said that - there may very well be a tool out there somewhere that handles this elegantly, but there's no avoiding the manual picking which strings need to be translated and which don't.
From I have learned and checked out, there no automated method to turn your strings to localized one you wish. But there's a plugin for XCode called Lin, that makes your process easy.
When you are focusing on NSLocalizedString or other functions to get a localized version of a string, Lin shows the list of localizations that contains the inputted key string.
Lin
From the question and your comments it seems you have around 400 strings only 20 of which should not be localised. With that ratio, as you yourself say, changing them all and then undoing the change for 20 can make sense.
To do this get TextWrangler, or BBEdit, and perform a multi-file pattern matching search and replace. You can confine the search to files ending in .m or .h. The task will be quick and easy, apart from those 20...
HTH
So here is the whole story.
I have done alot of code for a lot of platforms.
I really like the concept that I have found in Java and .NET with a resource file that can contain all the strings you will use in your app. Hopefully some of you know about it. It's basically an XML file sorted in a key=>value kind of way.
I have been looking for an equivalent in iOS but I'm unclear. There is infoPlist.strings, but that seems like the wrong path. I may be wrong.
So what we want is, we have a whole bunch of strings that get repeated in multiple places (alert boxes, direction text, etc.). We need that to be a change once kind of experience. There are multiple ways of doing this, I just don't know which one is the best.
I'm not really eloquent, so if anyone has questions or needs clarification, let me know.
If localization is not what you are trying to do, then you could just put them in a dictionary in a plist file. Have your app read the plist file at app startup and store in a global variable or some singleton that can be easily referenced throughout your app.
This is handled by the localization system. Look at NSLocalizedString() and Localizing String Resources. It should do exactly what you are looking for.
I don't know if my approach to this is fundamentally wrong, but I'm struggling to get my head around a (seemingly trivial?!) localisation issue.
I want to display the title of a 'System' UITabBarItem (More, Favorites, Featured, etc...) in a navigation bar. But where do I get the string from? The strings file of the MainWindow.nib doesn't contain the string (I didn't expect it to) and reading the title of the TabBarItem returns nil, which is what stumped me.
I've been told, there's no way to achieve it and I'll just have to add my own localised string for the terms in question. But I simply don't (want to) believe that!! That's maybe easy enough in some languages, but looking up, say, "More" in already presents me with more than one possible word in some languages. I'm not happy about simply sending these words for translation either, because it still depends on the translator knowing exactly which term Apple uses. So am I missing something simple here? What do other people do?
Obviously, setting the system language on my test device and simply looking to see what titles the Tab Items have is another 'obvious' possibility. But I really have a problem with half baked workarounds like that. That'll work for most languages, but I'm really gonna have fun when it comes to Russian or Japanese.
I'm convinced there must be a more reliable way to do this. Surely there must be a .strings file somewhere in the SDK that has these strings defined?
Thanks in advance...
Rich
The simple and unfortunate answer is that aside from a very few standard elements (e.g. a Back button), you need to localize all strings yourself. Yes, UIKit has its own Localization.strings file but obviously that's outside of your app sandbox so you don't have access to it.
I filed a bug with Apple years ago about providing OS-level localization for common button titles, tab item labels, etc. That bug is still open but obviously they haven't done it yet (sorry, I don't have the radar # handy).
I am writing a very simple application, for the iPhone. Unfortunately I am really a newbie.
What I am trying to do is to save data at the end of a user experience. This data is really simple, only string or int, or some array.
Later I want to be able to retrieve that data, therefore I also need an event ID (I suppose).
Could you please point out the best way, API or technology to achieve that, XML, plain text, serialization... ?
Use NSUserDefaults. Straight forward and easy to use. This will handle all File I/O for you, and takes only a couple lines of code.
NSUserDefaults is a good choice for small amounts of data.
If you need to manage something larger than a kilobyte or so, you might consider using the initWithContentsOfFile: methods of NSArray or NSDictionary to read in a .plist file. To write the file, use the writeToFile:atomically: methods. This file needs to go in your app's documents directory.
Me and my team created a simple class for this purpose which as Mark pointed out makes use of NSUserDefaults. Hopefully this helps you out...
http://getsetgames.com/2009/10/07/saving-and-loading-user-data-and-preferences/