Friday, October 10, 2008

Netflix API - Parsing the results of an API call - Part 5

One of the first API calls I needed to call gets the user's name and other information. In my case all I need is the first and last names, and the flag that says whether the user can use instant watching. This flag is set true for main accounts, and false for account profiles that don't have an instant queue.

The return data from the API call is in XML format, so this code shows how to use the XML parser to pick information out of the data returned from an API call. I provide a convenience method that combines the first and last names, and I didn't need the other link information, so it is ignored, but the code could easily be extended to pick it out as needed.

Some of the code below doesn't display properly. I'm going to set it up in google code soon to make it easier to manage.


//
// NetflixUser.h
// Instant Flix
//
// Created by Adrian Cockcroft on 10/8/08.
// Copyright 2008 millicomputing.com
// Licenced using Creative Commons Attribution Share-Alike
// http://creativecommons.org/licenses/by-sa/3.0/

#import


@interface NetflixUser : NSObject {
NSData *rawData;
NSString *first_name;
NSString *last_name;
bool can_instant_watch;
NSXMLParser *userParser;
NSString *currentElement;
}

@property(readonly) bool can_instant_watch;

- (NetflixUser *)initWithAPIResponse:(NSData *)response;
- (NSString *)name;

@end






//
// NetflixUser.m
// Instant Flix
//
// Created by Adrian Cockcroft on 10/8/08.
// Copyright 2008 millicomputing.com
// Licenced using Creative Commons Attribution Share-Alike
// http://creativecommons.org/licenses/by-sa/3.0/

#import "NetflixUser.h"

/* Sample returned raw data

[userid]
Adrian
Cockcroft
true













*/

@implementation NetflixUser

@synthesize can_instant_watch;

- (NetflixUser *)initWithAPIResponse:(NSData *)response {
rawData = response;
[rawData retain];
first_name = nil;
last_name = nil;
can_instant_watch = NO;

//NSString *responseBody = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
//NSLog(@"NetflixUser: %@", responseBody);

userParser = [[NSXMLParser alloc] initWithData:rawData];

// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[userParser setDelegate:self];
[userParser setShouldProcessNamespaces:NO];
[userParser setShouldReportNamespacePrefixes:NO];
[userParser setShouldResolveExternalEntities:NO];
[userParser parse];

return self;
}

- (NSString *)name {
return [first_name stringByAppendingFormat:@" %@", last_name];
}

- (void)parserDidStartDocument:(NSXMLParser *)parser{
//NSLog(@"started parsing");
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unable to parse XML (Error code %i)", [parseError code]];
NSLog(@"error: %@", errorString);
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//NSLog(@"found this element: %@", elementName);
currentElement = [elementName copy];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(@"ended element: %@", elementName);
currentElement = nil;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//NSLog(@"found characters: %@", string);
// save the characters for the current item...
if ([currentElement isEqualToString:@"first_name"]) {
first_name = [string copy];
} else if ([currentElement isEqualToString:@"last_name"]) {
last_name = [string copy];
} else if ([currentElement isEqualToString:@"can_instant_watch"]) {
if ([string isEqualToString:@"true"]) {
can_instant_watch = YES;
} else {
can_instant_watch = NO;
}
}
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
//NSLog(@"found %@ who %@ instant watch", self.name, (can_instant_watch? @"can": @"cannot"));
}

@end

1 comment:

Lawrence Ricci said...

Intereting post. I wonder what I could do with a millicomputer (soft of) running HD Video at 1.7Ghz

http://www.eurotech-inc.com/embedded-low-power-x86.asp

Devices and clouds- it ias the future. NIOce to see Netflix has a cloud.