Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group
This content has been archived.

Google Translate Tutorial for iOS: How To Translate Text With Google Translate and JSON on the iPhone

A Google translate tutorial on how you can easily use Google Translate to translate text into different languages on the iPhone.


  • Other, Other, Other
Funny Translation App We Will Build

Funny Translation App We Will Build

Google Translate provides a really neat API that you can use to quickly and easily use in your apps to translate text between tons of different languages.

In this Google Translate tutorial, we’re going to show you how you can use this API from your iPhone app to translate text a user enters in, back and forth from Japanese to English, until a “final match” is found, similar to the amusing Translation Party web page created by Will Carlough and Richard Boenigk.

This Google Translate tutorial will provide an introduction to JSON as well as the Google Translate APIs specifically. It is based upon an excellent tutorial on using JSON on the iPhone by Dan Grigsby at MobileOrchard (we miss you Dan!), but has more details on JSON for those who are new to the concept and information about the Google Translate API specifically.

What is JSON?

JSON is a simple human readable format that is often used to send data over a network connection.

For example, if you have an array of three strings, the JSON representation would simply be:

["test1", "test2", "test3"]

If you have a Pet object with member variables name, breed, and age, the JSON representation would simply be:

{"name" : "Dusty", "breed": "Poodle", "age": 7}

It’s that simple, which is why it’s so easy and popular to use. For the full spec, which can be read in just a couple minutes, check out the JSON format home page.

What is a JSON web service?

Many third parties such as Google or Yahoo! provide web services that return JSON formatted data when you visit a URL with a specified query string.

For the case of Google Translate’s web service, you can translate some text by issuing a GET request to the following URL:

When you issue the GET request, you need to pass some parameters to the web service. You do this by appending a query string to the end of the URL. In short, you begin the query string with a “?” and then add a sequence of “name=value” pairs, separated by the “&” symbol.

The web service defines which arguments need to be passed to the web service. For Google Translate, they have a nice definition of the Google Translate parameters that you can check out.

But the synopsis is to translate some text with Google Translate, you need to pass three arguments:

  • v: Short for “version”, and should always be set to 1.0
  • q: Short for “query”, and should be set to the text to translate.
  • langpair: Short for “language pair”, and should be set to a string containing the pair of two-letter language codes for the languages to translate, separated by a “|” sign.

Note that the values for each of these arguments needs to be escaped by adding percent escapes, according to the rules of URL encoding. For example, the “|” sign is escaped to “%7C”. Luckily, we don’t have to worry about this on the iPhone because there’s there’s a function in NSString that we can use to easily perform the required escaping.

So, the full URL with the query string to translate some text would look something like this:'s%20

Once you perform a GET request with that URL, Google will respond with a string that looks something like this:

{"responseData": {"translatedText":"\u3053\u3053\u3067\u3001\u30d0\u30b9\
    "responseDetails": null, "responseStatus": 200}

Based on what we know about JSON, this means that there is an object with three member variables: “responseData”, “responseDetails”, and “responseStatus”. In the case of “responseData”, that is a sub-object with a member variable of “translatedText”. The value of “translatedText” is just our escaped (Japanese in this case) string.

Ok – enough background, let’s get started!

Adding a JSON Framework to our project

Although you could write the code to parse this string yourself, it’s much easier and less error prone if you use one of the excellent libraries available to do so. For this Google Translate tutorial, we are going to use the Open Source Objective-C JSON framework developed by Stig Brautaset. So go ahead and visit site now and download the latest version of the framework.

Once you have it downloaded, make a new View-based Application in XCode and name the project GoogleTranslate. Right click on “GoogleTranslate” under “Groups & Files”, and click “Add\New Group” and name the group “JSON”. Then open the disk image of the JSON framework that you downloaded, open the JSON folder inside, and drag all of the files in that folder to the new “JSON” group you created in XCode. When the dialog pops up, verify that “Copy items into destination group’s folder (if needed)” is checked.

Next, open up GoogleTranslateViewController.m under Classes and add the following import to the top of the file:

#import "JSON.h"

Compile your project – if it compiles OK you’ve successfully integrated the JSON framework!

How the JSON Framework Works

The main class in the JSON Framework is named SBJsonParser. Once you get the JSON results from the web server, you pass it to the SBJsonParser via the objectWithString method. The parser will do all of the work to parse the string and convert the values into the most appropriate Objective-C type.

The JSON datatypes are converted to Objective-C types as follows (from SBJsonParser.h):

  • Null -> NSNull
  • String -> NSMutableString
  • Array -> NSMutableArray
  • Object -> NSMutableDictionary
  • Boolean -> NSNumber (initialised with -initWithBool:)
  • Number -> NSDecimalNumber

So in our case, the response from Google Translate would be converted into an NSMutableDictionary with three keys: responseData, responseDetails, and responseStatus.

The one we care about the most is responseData. It’s actually another NSMutableDictionary with just one key: translatedText. And translatedText is a simple NSString – the result we’re looking for!

Ok we’re really done with background information for real now! Let’s set up our interface.

Creating the Interface

Before we begin, let’s set up some member variables in our GoogleTranslateViewController class so we can hook them up with Interface Builder shortly. Open up GoogleTranslateViewController.h and edit the file to look as follows:

#import <UIKit/UIKit.h>

@interface GoogleTranslateViewController : UIViewController {
    IBOutlet UITextView *textView;
    IBOutlet UITextField *textField;
    IBOutlet UIButton *button;

- (IBAction)doTranslation;


Now expand the Resources tab and open up the GoogleTranslateViewController.xib. Open up the main view, and use the library to add a text field view, button, text view, and label to look like the following:

Layout in IB for our View

In the properties, remove all of the text in the Text View, and unclick “Editable”. Then, control-drag from the File’s Owner to the text view, text field, and button in the XIB window and connect them to their outlets. Finally, control drag from the button back to the File’s Owner to connect the doTranslation callback.

Save your XIB and compile and run the project to make sure that everything shows up OK so far. But don’t click the button yet, we haven’t actually written the callback! :]

Performing the Translation

We are going to retrieve the JSON response from the web server asynchronously. This means that rather than using initWithContentsOfURL – which is a no-no because it makes the interface unresponsive while the download is taking place – we will register ourselves as a delegate so we get notifications as the data is being downloaded in the background.

So to accomplish this, add three more member variables to your class in GoogleTranslateViewController.h:

NSMutableData *responseData;
NSMutableArray *translations;
NSString *_lastText;

And one property:

@property (nonatomic, copy) NSString * lastText;

Then go to GoogleTranslateViewController.m and add the following header:

#import "JSON.h"

And the following line right under the @implementation:

@synthesize lastText = _lastText;

And modify the dealloc method to include our cleanup code before we forget:

- (void)dealloc {
    [translations release];
    [_lastText release];
    [super dealloc];

Last piece of grunt work – create the translations array in the viewDidLoad method as follows:

- (void)viewDidLoad {
    [super viewDidLoad];
    translations = [[NSMutableArray alloc] init]; 

Ok – now time to perform the translation. Add the following methods to the bottom of the file:

- (void)performTranslation {
    responseData = [[NSMutableData data] retain];
    NSString *langString = @"en|ja";
    NSString *textEscaped = [_lastText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *langStringEscaped = [langString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *url = [NSString stringWithFormat:@"",
                     textEscaped, langStringEscaped];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];

- (IBAction)doTranslation {
    [translations removeAllObjects];
    [textField resignFirstResponder];
    button.enabled = NO;
    self.lastText = textField.text;
    [translations addObject:_lastText];
    textView.text = _lastText;    
    [self performTranslation];

Let’s look at doTranslation first. In this method, we clear out our member variable that we are going to use to store the translations. We also remove the keyboard from the display by calling resignFirstResponder on the text field. We set the button to disabled, store away the text that the user wants to translate in lastText and set the initial value of the text view to that value, and then call the performTranslation method.

In performTranslation, we first initialize an NSMutableData object that will be used to store the JSON response as it comes back from the server.

We then construct the URL to retrieve the translation from the Google server, using stringByAddingPercentEscapesUsingEncoding in order to escape our string properly.

Finally, we create an NSURLConnection with a NSURLRequest in order to start the process of downloading the data asynchronously. We set ourselves as the delegate so we will receive callbacks when the data arrives.

So let’s write those callbacks now! Add the following to the bottom of the file:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [responseData setLength:0];

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [responseData appendData:data];

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    textView.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];
    button.enabled = YES;

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];
    NSMutableDictionary *luckyNumbers = [responseString JSONValue];
    [responseString release];
    if (luckyNumbers != nil) {
        NSDecimalNumber * responseStatus = [luckyNumbers objectForKey:@"responseStatus"];
        if ([responseStatus intValue] != 200) {
            button.enabled = YES;
        NSMutableDictionary *responseDataDict = [luckyNumbers objectForKey:@"responseData"];
        if (responseDataDict != nil) {
            NSString *translatedText = [responseDataDict objectForKey:@"translatedText"];
            [translations addObject:translatedText];
            self.lastText = translatedText;            
            textView.text = [textView.text stringByAppendingFormat:@"\n%@", translatedText];
            button.enabled = YES;

Most of this is the pretty standard method way to collect the data as it comes in our NSMutableArray (responseData).

However the real fun occurs in connectionDidFinishLoading. We convert our NSData to a string, and then call a shortcut extension on NSString to invoke the JSON parser and convert the JSON string into the appropriate object (we know in this case that it will be a NSMutableDictionary). Note that we could have done this same thing by instantiating a SBJsonParser object and calling objectWithString – but this is just a bit simpler.

We then look inside the response, check the status to make sure we were successful, and then get the sub-dictionary of “responseData”. We then pull our the translated text, and add the results to the text view.

Compile and run your project, and if all works well you should see something like the following:

Our first translation

Finishing Touches

Now let’s add a little fun to the project and keep performing the translations back and forth until we arrive at a final result. Modify the beginning of your performTranslation method to look as follows:

- (void)performTranslation {
    // Break if we exceed limit
    if (translations.count > 50) {
        button.enabled = YES;
    responseData = [[NSMutableData data] retain];
    BOOL translateToEnglish = ([translations count] % 2 == 0);
    // Bail if we have a match
    if (!translateToEnglish && [translations count] >= 3) {
        NSString *oldString = [translations objectAtIndex:[translations count] - 3];
        if ([oldString caseInsensitiveCompare:_lastText] == NSOrderedSame) {
            button.enabled = YES;
    NSString *langString;
    if (translateToEnglish) {
        langString = @"ja|en";        
    } else {
        langString = @"en|ja";
    NSString *textEscaped = [_lastText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

Here we just add a little fun logic into the mix. We bail out if we’ve performed over 50 back and forth translations. We figure out if we’re translating to English or not by checking the size of our translation array – we alternate between English and Japanese, so every time the count is divisible by 2, we must be trying to translate some Japanese to English.

We check to see if the last English result matches the current English result, and we know we’re done if it matches. Lastly, we set the language string to alternate based on what we’re trying to do.

Now navigate to the connectionDidFinishLoading method. Add the following line inside at the end of the if (responseDataDict != nil) block:

[self performTranslation];

Compile and run the project, and you now should see some amusing results! Funny how much is lost in translation!

Screenshot of A Full and Amusing Translation

Can I Use Google Translate in My App?

If your app is free, definitely.

But if your app is paid, it’s a good question. According to the Google AJAX API Terms of Service, generally the implementation of Google Translate in your application must be available free of charge. So it’s pretty clear that Google wouldn’t allow you to whip up an app that is just a wrapper over Google Translate and sell it as-is.

However it’s a bit more unclear what is allowed when you have significant other features in your app, and Google translate is just one part of that. Some people on the Google AJAX forums believe that as long as you aren’t charging for the translation results specifically and give attribution to Google, you’ll be OK. I’ve also seen people doing this already on the App Store and haven’t heard of any issues.

But neither I nor the other folks are lawyers, so you might want to consult with one if you want to use Google APIs in your app!

And that’s a wrap!

That’s all we’re going to cover for now with the Google Translate API and JSON. Hopefully, this was a good introduction to JSON for those of you who are new to it.

Here’s a sample project with all of the code we’ve developed in the above Google Translate tutorial.

Have you been using JSON in your apps in any cool or interesting ways? Please share any tips or advice you may have below!



Create your free learning account today!

With a free account, you can download source code from our tutorials, track your progress, personalize your learner profile, participate in open discussion forums and more!