从RSS Feed创建NSDictionary?

Jum*_*hyn 0 xml iphone objective-c nsdictionary

我用Google搜索了一下,但在这个问题上找不到很多东西.我有一个RSS提要的URL,我想知道如何以NSDictionary的形式将该内容放入我的应用程序.我可以使用NSData的initWithContentsOfURL吗?

MiK*_*iKL 8

你需要两件事:

  1. 以XML格式检索RSS的内容
  2. 解析检索到的XML文件

检索RSS提要数据

Apple文档包含许多使用Web服务检索数据的示例NSURLConnection.Apple文档中提供了大量示例.以下是要点.

首先,您需要使用正确的URL初始化连接并启动它.下面的代码显示了如何执行此操作:

// Create a URL for your rss feed
NSURL *url = [NSURL URLWithString:@"http://yourrssfeedurl"];    
// Create a request object with that URL
NSURLRequest *request = [NSURLRequest requestWithURL:url 
                                         cachePolicy:NSURLRequestReloadIgnoringCacheData
                                     timeoutInterval:30];

// Clear the existing connection if there is one
if (connectionInProgress) {
    [connectionInProgress cancel];
    [connectionInProgress release];
}

// Instantiate the object to hold all incoming data
[receivedData release];
receivedData = [[NSMutableData alloc] init];

// Create and initiate the connection - non-blocking
connectionInProgress = [[NSURLConnection alloc] initWithRequest:request 
                                                       delegate:self 
                                               startImmediately:YES];
Run Code Online (Sandbox Code Playgroud)

在此代码中,connectionInProgressNSURLConnection执行连接的类中定义的类型的ivar .

然后,您需要实现NSURLConnectionDelegate方法:

// This method is called everytime the current connection receives data
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [receivedData appendData:data];
}

// This method is called once the connection is completed
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSString *xmlCheck = [[[NSString    alloc] initWithData:receivedData
                                        encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"xmlCheck = %@", xmlCheck);

    // Release our memory: we're done!
    [connectionInProgress release];
    connectionInProgress = nil;

    [receivedData release];
    receivedData = nil; 
}

// This method is called when there is an error
-(void) connection:(NSURLConnection *)connection 
  didFailWithError:(NSError *)error
{
    [connectionInProgress release];
    connectionInProgress = nil;

    [receivedData release];
    receivedData = nil;

    NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];

    NSLog(@"%@", errorString);
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中receivedDataNSMutableData执行连接的类中定义的类型的ivar .

解析XML

使用NSXMLParser该类解析刚刚检索到的xml文件非常简单.

调用解析器的类需要实现NSXMParserDelegate协议.这是在处理解析的对象的.h中完成的(本例中为DataManager):

@interface DataManager : _DataManager <NSXMLParserDelegate>
{
}
Run Code Online (Sandbox Code Playgroud)

在实现文件中,您需要至少实现以下方法:

每次在xml文件中找到新的XML标记时,该方法都会调用.这通常是您要定义新对象的位置,以便您可以在读取时设置其属性,或者清除用于存储XML文件中的字符的字符串.

- (void)parser:(NSXMLParser *)parser 
didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict
Run Code Online (Sandbox Code Playgroud)

每次解析器在文件中找到字符(而不是元素名称)时,该方法都会调用.这currentElementString是一个'NSMutabletring'类型的ivar.

- (void)parser:(NSXMLParser *)parser 
foundCharacters:(NSString *)string
{
    [currentElementString appendString:string];
}
Run Code Online (Sandbox Code Playgroud)

最后,只要读完元素就调用该方法.这通常是您将任何完全解析的元素存储到数据结构层次结构(字典或其他)中的位置:

- (void)parser:(NSXMLParser *)parser 
 didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName
Run Code Online (Sandbox Code Playgroud)

当您告诉解析器这样做时,解析开始.这是一个同步调用,即它将阻止您的应用程序,直到解析结束.以下是定义解析器并调用它的方法:

// Create an XML parser with the data received from the web service
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

// Give the parser  delegate
[parser setDelegate:self];

// Tell the parser to start parsing - The complete document will be parsed and the delegate to 
// of NSXMLParser will get all of its delegate messages sent to it before this line finishes
// execution. The parser is blocking.
[parser parse];

// Parser has finished its job, release it
[parser release];
Run Code Online (Sandbox Code Playgroud)

最后一条建议.通常,你会在didStartElement和didEndElement方法中有一个很大的if ... else if语句,你需要将elementName与你期望的元素的名称进行比较.建议使用常量字符串定义,您可以在两种方法中使用,而不是在方法中键入字符串.这意味着:

static NSString *ks_ElementName1 = @"ElementName1";
Run Code Online (Sandbox Code Playgroud)

应该在didStartElement和didEndElement方法中声明和使用,以在XML中标识"ElementName1".

Voilà,祝你的应用好运.