Using Google Web APIs in a Mac OS X Application

Introduction

Google has some APIs so you can get at their search engine. These APIs are based on SOAP and WSDL, so you can use a number of programming languages with them. For this example, we only care about using Objective C and Mac OS X. I don't care if you don't like square brackets. Get over it, dinosaur.

The API

Whenever someone says something like SOAP, WSDL, or XML-RPC, it's time to pull out the WebServices framework. It's the cat's pajamas. This API does SOAP and XML-RPC. I don't know how all that stuff works. I just know it's a remote procedure call API that uses HTTP, and thanks to WebServices, that's about all I need to know.

When you download the Google Web APIs developer's kit, it comes with a WSDL file. This is some standard format to describe the ins and outs of each API. We can run a WebServices tool on it to convert the WSDL file into an Objective C header and implementation file. The tool can also do C++ or AppleScript, but we're not interested in that now.

What my sample app looks like

This is what the app I wrote looks like. It's a completely useless app. I'm just here to show you how to use the API.

In the top I enter my search terms and my Google Developer Key. The next text field shows the actual result coming back from Google. The next table shows the results in a table. When you click on a result, a summary appears in the bottom text field. Useless app.

How did I do it?

I was reading the online documentation for WebServices and saw it talk about WSDL. The framework does not support WSDL yet, but they have a tool that converts WSDL to source files for you. So this is what I did:

/Developer/Tools/WSMakeStubs -x ObjC -dir ~jav/Projects/GoogleXML/ -file /Volumes/7B85/Users/jav/Desktop/googleapi/GoogleSearch.wsdl

This creates WSStub.* and WSGeneratedObj.*. WSGeneratedObj.* contains generic code, and WSStub.* contains code for the APIs in the WSDL file you gave it.

So now the only code I have to write is the code in my controller class that makes the remote procedure call and put the result in the UI. Here's that function.

// -----------------------------------------------------------------------
// * doSearch
// -----------------------------------------------------------------------
- (IBAction)doSearch:(id)sender
{
		// get the query
	NSString* query = [searchField stringValue];
	
		// get the Google Developer API key.  Dont' use mine, get your own.
	NSString* googleKey = [googleDevKeyField stringValue];
	
		// make me one of them WSGeneratedObj just for making the search API call.
		// doGoogleSearch is declared in WSStub.h, and is a subclass of WSGeneratedObj.
	doGoogleSearch* doSearch = [[doGoogleSearch alloc] init];
	
		// now feed it a bunch of parameters.
	[doSearch setParameters:googleKey
				in_q:query
				in_start:1
				in_maxResults:10
				in_filter:YES
				in_restrict:@""
				in_safeSearch:NO
				in_lr:@"lang_en"
				in_ie:@""
				in_oe:@""];
		
		// this performs the actual remote procedure call
	NSDictionary* result = [doSearch resultValue];
	
		// put the exact result in the UI so geeks can read it
	[resultField insertText:[[doSearch getResultDictionary] description]];
	
		// we're done with this thing
	[doSearch release];
	
		// retain the search results so we can populate UI here and there
	[searchResults release];
	searchResults = [[result objectForKey:@"resultElements"] retain];
	
		// tell our table we have new results
	[resultsTable reloadData];
}

I put comments in my code, so I shouldn't have to explain anything more, unless you're not as smart as me.

Download my project

I did all the work, and now you can download free code. Lucky you. Consider sending me money.

Download (68K)
(68K refers to the size of the download. I do not mean to suggest that this code will only compile on the Motorola 68000 series of microprocessors.)

Extreme Mac OS X Programming. Copyright © 2004 John A. Vink