NSXmlParser с UITableView не загружает строки - PullRequest
0 голосов
/ 15 июня 2011

хорошо, поэтому я пытаюсь проанализировать данные XML в таблицу, это код, который у меня есть в настоящее время, он не показывает имя в каждой строке таблицы, и я думаю, что мой код очень неэффективен, потому что я прочитал из двухразные книги и старались изо всех сил, чтобы все работало вместе.Пожалуйста, могу предложить улучшения кода и исправить мою проблему, спасибо: D Я также знаю, я еще ничего не выпустил, собирался сделать это позже:)

#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;
}

1 Ответ

1 голос
/ 16 июня 2011

после того, как ваши данные готовы для отображения в табличном представлении, вы должны вызвать reloadData, чтобы снова вызвать методы делегата UITableView.

-(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];
}

Что касается синтаксического анализа и асинхронного запроса, кажется, что вы делаете правильный путь, так как NSURLConnection и NSXMLParser используют шаблон делегирования для работы.

Некоторые считают, что некоторые люди могут сказать, что для повышения производительности можно заменить NSURLConnection на ASIHttpRequest и, возможно, использовать стороннюю XML-библиотеку для более быстрого и простого анализа ваших данных (здесь хорошая статья о горячем выборе лучшего парсера xml для вашего приложения )

...