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
        NSString *feedName = [[feed_type selectedItem] title];
        feedName = [feedName lowercaseString];
        feedName = [feedName stringByReplacingOccurrencesOfString:@" " withString:@"_"];

        NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForFeedID:feedName];
        ticket = [service fetchYouTubeFeedWithURL:feedURL

    [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.