Monday, April 4, 2011

Learning While Coding

The last week or so at work has had me learning how to do some things for when I program which I never expected. They are all things that are important things to be able to do, and a few aren't as difficult as one would expect, though the major one (which I will get to) has been giving me utter headaches, because it leads to a rather large change in programming style and way of thinking.

Warning, heavy geekery ahead. Though really, on this blog, would you expect anything else?

To begin with, Localisation of applications. This is quite a big thing on, well, any piece of software. How do you write a program to work in any language? To make it display properly in Japanese, Chinese, Russian? Apart from the obvious issue of needing someone to translate for you (if you do not know the language), you also need a way to make it easy to inject these language options into your software. For example, if you hardcode all of your strings, then for every language version you need to find where all of these are coded, then change them for each language, then recompile many different language versions. This is completely unmanageable!

Luckily, for me at least as an iPhone programmer, Apple have made it easy. It seems so alien to me, having something from Apple which simply works for a change (my work laptop is living proof to me that the Mac elitist pricks who tell me that Macs are superior to PCs simply are spending too much time staring lovingly at the form of the computer, rather than the fact that the screen is showing that all your apps have frozen)!
To localise an iPhone app, all you need to do is create a strings file (called Localizable.strings - remembering that its z is important because they're American and can't spell. Also, a lost of configuration stuff is skipped by using this particular filename, since its the default), and define a bunch of variables in there. Once you have done that, wherever you code a string in the app itself, replace with the following piece of code:

NSLocalizedString(@"TITLE", nil)

where "TITLE" is the name of the variable, and the second parameter is simply space for a comment to assist a translator with (context matters a LOT in language).
Of course, there is a little bit more to it - you still need to actually localise your strings file. In xCode 4, all you do is go to the localise panel on the right, and add a localisation to your strings file. It asks you what language it is for (since the iPhone will use default language settings based on what the user picks). Then, simply change the variables you set in the above one to the language specific strings. Sorted!

It gets slightly more complex when you are localising images and interface layouts (due to button sizes and things), but this is the general workflow of it. Not bad at all!
(Also, Ray Wenderlich's site is where I found the tutorial that taught me this. Awesome site full of tutorials. Don't freak out when you see the "I'm quitting iOS" post - its an April Fool's troll)

 
Unrelated: Rocks fall, everyone dies

Another important thing I've been learning as part of work the last few days has been how to use a Unit Testing framework for the iPhone. Unit testing is an important part of programming. At least, that's what I've heard - I've yet to see results from it, because all I've been doing is learning how to do it, how to combine it with Mock Objects, and trying to get my head around this enough to write some useful tests.

The theory behind it is that if I write a test that ensures I get correct output from a function I write, then later on if I change the function (refactoring, optimisation, etc), then I can rerun the tests. If the tests fail, then obviously I've changed something to the point where it breaks - aka failed refactoring, where the actual processing has changed. Sounds useful huh?

Well, even more than that, once I've caught up on the tests I should have been writing, I can use this for TDD - Test Driven Development. This is where we write the tests BEFORE the code is actually written. The purpose of this is to force me to think about what is actually needed (in terms of variables and functions), and then ensure that each function works before I move onto something else (since its always nice to see green lights as irrevocable proof that your code works).

As you can probably tell, this is a far cry from my usual method of "think about the system, design some objects, start writing, run the app to see if it works". Hopefully, this'll work much better.

Its just doing my head in at the moment.

I won't go into details on how to get it working on the iPhone, since there are many ways to do it (and this post will go insanely long, and overly technical for those not so code minded), though I will mention that I'm using GHUnit-iPhone for a test suite, and OCMock for the Mock Objects, if you are interested in taking a look.

I will probably integrate some of this onto my home machine so I can work from home if required - and possibly more importantly, for my own work (which has yet to begin / be designed).

No comments:

Post a Comment