@property id <NSXMLParserDelegate> xmlRootObject


#1

Hi

In the actor design pattern section of this chapter, we define a BNRConnection object, with this property :

@property (nonatomic, strong) id <NSXMLParserDelegate> xmlRootObject;

I was surprised by the "id " part of the property.
Could you please explain this way to declare a property ? Did we encounter this previously in the book ?

Thank you
Fred


#2
@property (nonatomic, strong) id <NSXMLParserDelegate> xmlRootObject;

What this is saying is that xmlRootObject’s class conforms to the NSXMLParserDelegate protocol.

It provides the compiler or Xcode or humans with more static type information than in:

@property (nonatomic, strong) id xmlRootObject;

or than in:

@property (nonatomic, strong) SomeXMLType *xmlRootObject;

(As you already know, id can stand forn any object pointer.)


#3

OK, thanks for your answer !
I didn’t know you could declare a property this way, very useful !

Fred


#4

Hi,

This relates to the use of xmlRootObject and conceptually it is giving me a bit of a hard time. Was wondering if anyone could verify my understanding below? Thanks!

Before we set up the BNRFeedStore (chapter 26), the way we parsed the XML file and knew how to identify was via

ListViewController.m

- (void)connectionDidFinishLoading:(NSURLConnection *)conn { NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData]; [parser setDelegate:self]; [parser parse]; ....}

Then the parser starts and we have

ListViewController.m

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { NSLog(@"%@ found a %@ element", self, elementName); if ([elementName isEqual:@"channel"]) { channel = [[RSSChannel alloc] init]; [channel setParentParserDelegate:self]; [parser setDelegate:channel];} }

This all makes sense. We find an elementName through the parser’s didStartElement (parser living in ListViewController) and once it was the string “channel”, assign an instance of RSSChannel and it gets to work.

Now with the migration to the BNRFeedStore, how is the logic?

fetchRSSFeedWithCompletion in ListViewController kicks off --> which calls “start” in BNRFeedStore.h --> which calls connectionDidFinishLoading in BNRConnection.h when done. But at what point does it say “If you see then that is an element we are interested in and parse according to this string”?

I can only narrow it down to the line

but this is confusing because i can’t see how RSSChannel.m will know when and what to start looking for. Do we not need to set the property parentParserDelegate anymore?
Would greatly appreciate if someone could explain it some more! Thank you!

(The Nerdfeed chapters are great btw :slight_smile:)


#5

[quote]I can only narrow it down to the line

    [code][parser setDelegate:[self xmlRootObject]];[/code]

but this is confusing because i can’t see how RSSChannel.m will know when and what to start looking for. Do we not need to set the property parentParserDelegate anymore?[/quote]

Inside BNRFeedStore’s fetchRSSFeedWithCompletion: method you create an empty RSSChannel object and set it as the rootXmlObject of the BNRConnection object. BNRConnection fills up that RSSChannel object with data. When that finishes then connectionDidFinishLoading: gets called. Inside this method the NSXMLParser object is created. We set it’s delegate to be the RSSChannel (xmlRootObject) and the parser parses it.

Hope that helps,
mb