开发者

NSXmlParser with UITableView not loading rows

ok so I am trying to parse XML data into a ta开发者_如何学运维ble, this is the code I currently have, it is not showing the name within each row on the table and I think my code is very inefficient because I have read from two different books and tried my best to get everything working together. Please can to suggest code improvements and a fix for my issue thanks :D I am also aware, I havent released anything yet, was going to do that at a later date :)

#import "firstLevelViewController.h"
#define INTERESTING_TAG_NAMES @"text", @"name", nil

@implementation firstLevelViewController
@synthesize tweetsData;
@synthesize userArray;
@synthesize tableArray;


-(void)viewDidLoad
{
    self.userArray = [[NSMutableArray alloc] init];
    interestingTags = [[NSSet alloc] initWithObjects: INTERESTING_TAG_NAMES];

    self.title = @"test";

    [tweetsData release];
    tweetsData = [[NSMutableData alloc] init]; //alloc the holder for xml, may be large so we use nsmutabledata type

    NSURL *url = [NSURL URLWithString:@"http://twitter.com/statuses/public_timeline.xml"];//url string to download

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; //set a request with the url

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //start the connection and call connection methods from below

    [connection release];
    [request release];
}

//called various times
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"didReceieveData Connection");
    [tweetsData appendData:data]; //append data from method call line to tweetsData tweetsData now holds xml file
}


//called after downloaded finished
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"finished");
    [self startParsingTweets];  
}

//*****************************START PARSER CODE************************************

-(void)startParsingTweets
{
    NSLog(@"parsing init");
    NSXMLParser *tweetParser = [[NSXMLParser alloc] initWithData:tweetsData]; //uses the NSMutableData data type to parse
    tweetParser.delegate = self; //set the delegate to this viewControlelr
    [tweetParser parse];
    [tweetParser release];
}

//called when the document is parsed
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"parsing started");
    [tweetsString release]; //make sure its empty to get rid of any previous data

    tweetsString = [[NSMutableString alloc] initWithCapacity:(20 * (140 + 20))]; // ( number of calls * ( size of tweet + username )
    currentElementName = nil;
    currentText = nil;
}

//this is called for each xml element
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"started element");
    if ([elementName isEqualToString:@"status"]) //if elementName == status then start of new tweet so make new dictionary
    {
        [currentTweetDict release];
        currentTweetDict = [[NSMutableDictionary alloc] initWithCapacity:[interestingTags count]]; //make dictionary with two sections
    }
    else if([interestingTags containsObject:elementName]) //if current element is one stored in interesting tag, hold onto the elementName and make a new string to hold its value
    {
        currentElementName = elementName; //hold onto current element name
        currentText = [[NSMutableString alloc] init];
    }

}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    NSLog(@"appending");
    [currentText appendString:string];
}

//after each element it goes back to the parent after calling this method
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:currentElementName])
    {
        [currentTweetDict setValue: currentText forKey: currentElementName];
    }
    else if([elementName isEqualToString:@"status"])
    {
        [self.userArray addObject:currentTweetDict];

        //eventually placed in table just testing for now

    }

    [currentText release];
    currentText = nil;
}

-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    for(int i=0;i<[self.userArray count];i++)
    {
        NSDictionary *rowData = [self.userArray objectAtIndex:i];
        NSString *textName = [[NSString alloc] initWithFormat:@"user: %@", [rowData objectForKey:@"name"]];
        [self.tableArray addObject:textName];
    }

        NSLog(@"done");

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.userArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *FirstLevelIdentifier = @"FirstLevelIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelIdentifier];

    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelIdentifier];
    }

    NSUInteger row = [indexPath row];
    NSDictionary *rowData = [self.tableArray objectAtIndex:row];
    NSString *textName = [[NSString alloc] initWithFormat:@"user: %@", [rowData objectForKey:@"name"]];
    cell.textLabel.text = textName;

    return cell;
}


after your data is ready to be displayed on the table view, you should call reloadData to make the UITableView delegate methods be called again.

-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    for(int i=0;i<[self.userArray count];i++)
    {
        NSDictionary *rowData = [self.userArray objectAtIndex:i];
        NSString *textName = [[NSString alloc] initWithFormat:@"user: %@", [rowData objectForKey:@"name"]];
        [self.tableArray addObject:textName];
    }

        NSLog(@"done");

     //reloadData so that the table view delegate get called again
     [self.tableView reloadData];
}

As for the parsing and the async request, it seems you are doing the right way as both NSURLConnection and NSXMLParser use the delegation pattern to work.

Some thinks some people might say that you could do to improve performance is replacing NSURLConnection for ASIHttpRequest, and may be use other 3rd party XML library to parse your data faster and easier (here is a nice article about hot to choose the best xml parser for your app)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜