The Cocoa and Cocoa Touch frameworks has a really nice function for acquiring a localized string
NSLocalizedString()
. Just pass in a key and you are done, for strings that are known at least. Sometimes you are getting unknown strings from a data source not under your control, strings representing just a fraction of the text in your UI. Leaving this text in it's source language looks weird, and skipping translation all together just feel wrong.Google Translate to the rescue
Turns out that Google Translate has a nice AJAX API, feed it a URL request and get a JSON response. Admittedly the translations are not always perfect, even quite humorous at times, but good enough if you provide the user a warning.So let us create a sibling to
NSLocalizedString()
called CWTranslatedString()
. It should take two arguments; the string to translate, and the source language ISO code. We should also be able to get the users currently selected language, that will be used as the destination language when translating. So this is our header:NSString* CWCurrentLanguageIdentifier(); |
NSString* CWTranslatedString(NSString* string, NSString* sourceLanguageIdentifier); | | | | |
Currently your iPhone application must be terminated in order for the user to change the language. And even when Apple adds multitasking for third-party apps we can assume the user do not go about and switch languages too often, so we let
CWCurrentLanguageIdentifier()
cache the language code:NSString* CWCurrentLanguageIdentifier() { static NSString* currentLanguage = nil; if (currentLanguage == nil) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSArray* languages = [defaults objectForKey:@"AppleLanguages"]; currentLanguage = [[languages objectAtIndex:0] retain]; } return currentLanguage; }
Now for theCWTranslatedString()
function. The JSON response from Google Translate is well formatted with no line breaks, so let's not bother with a proper JSON-parser. We can use a simpleNSScanner
, and just return the source string for any unexpected result. We also short circuit and return the source string if the source and dest language as equal.
NSString* CWTranslatedString(NSString* string, NSString* sourceLanguageIdentifier) { static NSString* queryURL = @"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%@&langpair=%@%%7C%@"; if (sourceLanguageIdentifier == nil) { sourceLanguageIdentifier = @"en"; } if ([sourceLanguageIdentifier isEqual:CWCurrentLanguageIdentifier()] || string == nil) { return string; } NSString* escapedString = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString* query = [NSString stringWithFormat:queryURL, escapedString, sourceLanguageIdentifier, CWCurrentLanguageIdentifier()]; NSString* response = [NSString stringWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:NULL]; if (response == nil) { return string; } NSScanner* scanner = [NSScanner scannerWithString:response]; if (![scanner scanUpToString:@"\"translatedText\":\"" intoString:NULL]) { return string; } if (![scanner scanString:@"\"translatedText\":\"" intoString:NULL]) { return string; } NSString* result = nil; if (![scanner scanUpToString:@"\"}" intoString:&result]) { return string; } return result; }
And that is it. Not perfect, but nice to have.
No comments:
Post a Comment