MyTube, searching for fun and profit
On to our next installment of the MyTube saga. This time I’m taking a look at adding query capabilities to the application. The queries will run against all the videos but it should be pretty simple to update to make the queries run against the category selector as well. I’ll mention this when we get there.
Before I started into the query stuff I cleaned up a few of the loose ends that
have started to dangle since the start of this series. The first one was my lame
WebView bug. If you’ll remember in imageBrowser:cellWasDoubleClickedAtIndex:
I had a [web reload];
call in there. You’ll want to remove that. What I
ended up doing was setting the new video then reloading the old one. This was
the problem where it wasn’t always showing the correct video.
The other change I made was to cleanup the init
method of
MyTubeIKBrowserItem. I updated the function to have a the initVideo:image:
signature. A bit cleaner and simpler then before. When I need the image ID or
title I just grab it from the video object with [[video title] stringValue]
.
Those were the main, minor, changes I made so let’s get this party started.
First off add IBOutlet NSTextField *search_box;
to our MyTubeAppController
interface. We’ll be using this to get the search value entered into the
interface.
Now, double click on MainMenu.nib to start Interface Builder. From the Views & Cells section of the Library drag an NSTextField to the application window. With the text field selected open up the Inspector (apple-i). On the Information pane (apple-1) change the Action to Send on Enter Only. This way our backend code will only be called when the user hits enter. (Don’t worry, we’re also going to work if they press the Get Videos button). Oh, and that was the other change I made, I renamed the button to Get Videos.
With the text field still selected go to the Attributes pane (apple-5) of the
Inspector. In the Sent Actions section we want to grab the circle beside the
selector entry. We’ll then drag the mouse to the My Tube object in the control
window. When we release the mouse we’ll select grab:
in the window that pops
up. This hooks the text field up so when the user hits enter it will call our
grab method.
Now, in the control window right click on the My Tube object and drag the circle beside search_box to our new text field. We can now save and close Interface Builder.
All of our code changes will be in the grab:
method. We’ll be re-using the
same selectors to display the images as the combo box feed methods use.
- (IBAction)grab:(id)sender
{
GDataServiceGoogleYouTube *service = [self youTubeService];
GDataServiceTicket *ticket;
NSString *searchString = [search_box stringValue];
if ((searchString != nil) && ([searchString length] > 0))
{
NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForFeedID:nil];
GDataQueryYouTube *query = [GDataQueryYouTube youTubeQueryWithFeedURL:feedURL];
[query setVideoQuery:searchString];
ticket = [service fetchYouTubeQuery:query
delegate:self
didFinishSelector:@selector(entryListFetchTicket:finishedWithFeed:)
didFailSelector:@selector(entryListFetchTicket:failedWithError:)];
}
else
{
NSString *feedName = [[feed_type selectedItem] title];
feedName = [feedName lowercaseString];
feedName = [feedName stringByReplacingOccurrencesOfString:@" " withString:@"_"];
NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForFeedID:feedName];
ticket = [service fetchYouTubeFeedWithURL:feedURL
delegate:self
didFinishSelector:@selector(entryListFetchTicket:finishedWithFeed:)
didFailSelector:@selector(entryListFetchTicket:failedWithError:)];
}
[imageList removeAllObjects];
}
The else
section of the if statement is the same code as our previous
examples. It will be used if there is no value in the search box and just
retrieves the entries for a given video feed.
The interesting bit is the if
itself. So, what are we doing. First we grab
the string value of our search box and if it isn’t blank we’ll do a search
query. The query itself is similar to the code we use to retrieve the feeds.
We first construct the URL that we want to query. In this case you’ll notice I’m
passing nil
to the [GDataServiceGoogleYouTube youTubeURLForFeedID:nil]
call. Passing in nil
will give me the general video feed instead of a
specialized feed. This is also where we could put in a feed name to search the
specific feed instead of all videos.
Now that we’ve got our query URL we create a GDataQueryYouTube
object. This
will contain all of our query information. I then use the setVideoQuery
method to pass in the query string. There are a bunch of other query options
that can be used to limit date ranges, allow racy videos and other things. Take
a look at the query header to see the full set of methods. This will, I believe,
return a maximum of 999 videos.
With the query constructed we then use fetchYouTubeQuery
which is very
similar to the fetchYouTubeFeedWithURL
function we were using earlier.
That’s it. You should be able to run MyTube and query videos from YouTube.
You can grab the complete list of source code for MyTube at MyTube 0.4.