Creating NSDictionary from RSS Feed?
I Googled around a bit, but can't find a whole lot on the subject. I have the URL to an RSS feed, and I want to know how to go about getting that content into my app in the f开发者_如何转开发orm of an NSDictionary. Could I use NSData's initWithContentsOfURL?
You need two things:
- retrieving the content of your RSS in XML
- parsing the retrieved XML file
Retrieving the RSS feed data
The Apple documentation contains many examples of retrieving data from a web service using NSURLConnection
. Lots of examples are available on the Apple documentation. Here are the main points though.
First you need to initialize your connection with a proper URL and initiate it. The code below shows how to do this:
// 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];
In this code the connectionInProgress
is an ivar of type NSURLConnection
defined in the class performing the connection.
Then you need to implement the NSURLConnectionDelegate methods:
// 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);
}
In the code above receivedData
is an ivar of type NSMutableData
defined in the class performing the connection.
Parsing XML
Parsing the xml file you have just retrieved is quite straightforward using the NSXMLParser
class.
The class calling the parser needs to implement the NSXMParserDelegate
protocol. This is done like this in the .h of the object dealing with the parsing (DataManager in this example):
@interface DataManager : _DataManager <NSXMLParserDelegate>
{
}
And in the implementation file you need to implement at least the following methods:
The method called every time a new XML tag if found in your xml file. This is typically where you will either define new objects so you can set their properties as they are being read or where you will clear the string used to store the characters found in your XML file.
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
The method called every time the parser finds characters in your file (not elements names). Here currentElementString
is an ivar of type 'NSMutabletring'.
- (void)parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string
{
[currentElementString appendString:string];
}
Last the method called whenever reading of an element is completed. This is typically where you would store any completely parsed element into your data structure hierarchy (dictionary or otherwise):
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
The parsing starts when you tell the parser to do so. It's a synchronous call, i.e. it will block you application until the parsing is over. Here is how you define the parser and call it:
// 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];
One last piece of advice. Typically you will have a big if...else if statement in the didStartElement and didEndElement methods where you need to compare the elementName to the names of the elements you expect. It is advisable to use constant string definitions which you can use in both methods as opposed to typing the strings in the methods. This means this:
static NSString *ks_ElementName1 = @"ElementName1";
should be declared and used in both didStartElement and didEndElement methods to identify "ElementName1" in your XML.
Voilà, good luck with your app.
One note about using NSXMLParser -(void)initWithContentsOfURL:(NSURL *)url
instead of using NSURLConnection
to load the data. NSURLConnection
is non-blocking, loading the data in a separate thread managed by itself, calling the defined delegate when required. Conversely, the NSXMLParser initWithContentsOfURL
method will block if called on the main thread.
Check the documentation for the NSXMLParser Class. You can initWithContentsofURL and then manipulate the data how you see fit.
I once began a project which involved something like this which was abandoned for unrelated reasons. You should look into NSXMLParser (documentation link) to parse your XML feed. You can easily break up elements and add them into whatever data structure you like.
精彩评论