I figured out what the problem was and answering it here incase anyone else 
runs into this problem in the future since +[NSXMLParser initWithStream] 
doesn't have a lot lot of documentation out there. 
I needed to call -[NSXMLParser parse] right after I allocate NSXMLParser and 
set myself as delegate. But because it's a synchronous function, I need to call 
it another thread so I don't block the current thread and it can receive the 
NSStream events. I also don't need to make myself the delegate for 
NSInputStream.
This can be done pretty simply using Grand Central Dispatch (GCD) like so:
// alloc and init the xml parserxmlParser = [[NSXMLParser alloc] 
initWithStream:inputStream];[xmlParser setDelegate:self];
// block to executedispatch_block_t dispatch_block = ^(void){    [xmlParser 
parse];};
// create a queue with a unique namedispatch_queue_t dispatch_queue = 
dispatch_queue_create("parser.queue", NULL);
// dispatch queuedispatch_async(dispatch_queue, dispatch_block);
// cleanupdispatch_release(dispatch_queue);


And here is the complete working example, just incase anyone wasn't able to 
follow what I posted above.
ContentParser.h
@interface ContentParser : NSObject <NSStreamDelegate,                          
            NSXMLParserDelegate>{   NSInputStream *inputStream;   
NSOutputStream *outputStream;   NSMutableData *receivedData;   NSXMLParser 
*xmlParser;}- (void)initStream;ContentParser.m
@implementation ContentParser
- (void)initStream{       CFReadStreamRef readStream;   CFWriteStreamRef 
writeStream;
   CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,                      
                (CFStringRef)@"<hostname>",                                     
 <port>,                                      &readStream,                      
                &writeStream);
   inputStream = (__bridge NSInputStream *)readStream;   outputStream = 
(__bridge NSOutputStream *)writeStream;
   outputStream.delegate = self;
   [inputStream  scheduleInRunLoop:[NSRunLoop currentRunLoop]                   
        forMode:NSDefaultRunLoopMode];   [outputStream 
scheduleInRunLoop:[NSRunLoop currentRunLoop]                            
forMode:NSDefaultRunLoopMode];
   [inputStream open];   [outputStream open];
   xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];   [xmlParser 
setDelegate:self];
   dispatch_block_t dispatch_block = ^(void)   {      [xmlParser parse];   };
   dispatch_queue_t dispatch_queue = dispatch_queue_create("parser.queue", 
NULL);   dispatch_async(dispatch_queue, dispatch_block);   
dispatch_release(dispatch_queue);}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName    
                                     namespaceURI:(NSString *)namespaceURI      
                                  qualifiedName:(NSString *)qName               
                        attributes:(NSDictionary *)attributeDict{   
NSLog(@"didStartElement: %@, attributeDict: %@", elementName, attributeDict);}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{   
NSLog(@"foundCharacters: %@", string);}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName      
                                 namespaceURI:(NSString *)namespaceURI          
                            qualifiedName:(NSString *)qName{   
NSLog(@"didEndElement: %@", elementName);}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{  
 NSLog(@"Error %ld, Description: %@, Line: %ld, Column: %ld",       [parseError 
code], [[parser parserError] localizedDescription],       [parser lineNumber], 
[parser columnNumber]);}

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode{   
switch (eventCode) {      case NSStreamEventHasSpaceAvailable:      {         
/* write bytes to socket */         break;      }      default:         break;  
  }}
@end
----------------------------------------
> From: [email protected]
> Subject: NSXMLParser and initWithStream
> Date: Sun, 27 May 2012 20:14:16 -0400
> To: [email protected]
>
> I'm trying to use the NSStream classes to parse incoming incremental XML 
> data. The data is never a complete XML Document, but I want to receive and 
> process it in incremental chunks based off how much ever the socket can read.
>
> Looking at the documentation for NSXMLParser, it seems like the 
> initWithStream: method to initialize a NSXMLParser would be the perfect 
> solution to my problem. I can initialize the parser with a NSInputStream and 
> then call the parse method on NSXMLParser whenever I receive data over my 
> socket which should in turn call the NSXMLParser delegates.
>
> However, I'm not seeing any of the delegates being called, the only method I 
> see being called is the stream delegate stream:handleEvent:. There seems to 
> be little to no examples of this API from Apple or other developers. I could 
> use libxml2 directly to accomplish what I want, but I am hoping I am just 
> using NSXMLParser incorrectly.
>
> Here is the source for what I am trying:
>
> ContentParser.h:
>
> @interface ContentParser : NSObject <NSStreamDelegate,
> NSXMLParserDelegate>
> {
> NSInputStream *inputStream;
> NSOutputStream *outputStream;
> NSMutableData *receivedData;
> NSXMLParser *xmlParser;
> }
> - (void)initStream;
>
> ContentParser.m:
>
> @implementation ContentParser
>
> - (void)initStream
> {
> CFReadStreamRef readStream;
> CFWriteStreamRef writeStream;
>
> CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
> (CFStringRef)@"<hostname>",
> <port>,
> &readStream,
> &writeStream);
>
> inputStream = (__bridge NSInputStream *)readStream;
> outputStream = (__bridge NSOutputStream *)writeStream;
>
> inputStream.delegate = self;
> outputStream.delegate = self;
>
> [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
> forMode:NSDefaultRunLoopMode];
> [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
> forMode:NSDefaultRunLoopMode];
>
> [inputStream open];
> [outputStream open];
>
> xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];
> [xmlParser setDelegate:self];
> }
>
> - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
> namespaceURI:(NSString *)namespaceURI
> qualifiedName:(NSString *)qName
> attributes:(NSDictionary *)attributeDict
> {
> NSLog(@"didStartElement: %@, attributeDict: %@", elementName, attributeDict);
> }
>
> - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
> {
> NSLog(@"foundCharacters: %@", string);
> }
>
> - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
> namespaceURI:(NSString *)namespaceURI
> qualifiedName:(NSString *)qName
> {
> NSLog(@"didEndElement: %@", elementName);
> }
>
> - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
> {
> NSLog(@"Error %ld, Description: %@, Line: %ld, Column: %ld",
> [parseError code], [[parser parserError] localizedDescription],
> [parser lineNumber], [parser columnNumber]);
> }
>
>
> - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
> {
> switch (eventCode) {
> case NSStreamEventHasBytesAvailable:
> {
> if (stream == inputStream) {
> NSInputStream *is = (NSInputStream *)stream;
> if (receivedData == nil) {
> receivedData = [[NSMutableData alloc] init];
> }
>
> uint8_t buf[1024];
> NSInteger bytesRead = [is read:buf maxLength:1024];
> if (bytesRead == -1) {
> NSLog(@"Network read error");
> } else if (bytesRead == 0) {
> NSLog(@"No buffer received");
> } else {
> [receivedData appendBytes:buf length:bytesRead];
> BOOL parserResult = [xmlParser parse];
> if (parserResult == NO) {
> NSLog(@"Unable to parse XML");
> }
> }
> }
> break;
> }
> default:
> break;
> }
> }
>
> @end
> _______________________________________________
>
> Cocoa-dev mailing list ([email protected])
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/smq4z1%40hotmail.com
>
> This email sent to [email protected]
                                          
_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to