Использование NSXMLParser initWithStream: методы-делегаты парсера не получены
Основная проблема, над которой я работаю, заключается в использованииNSStream
классы для разбора входящих инкрементальных данных XML. Данные никогда не являются полным XML-документом, но я хочу получать и обрабатывать их постепенно, исходя из того, сколько раз сокет может читать.
Глядя на документацию дляNSXMLParser
кажется, чтоinitWithStream:
метод для инициализацииNSXMLParser
было бы идеальным решением моей проблемы. Я могу инициализировать парсер сNSInputStream
а затем позвонитеparse
метод наNSXMLParser
всякий раз, когда я получаю данные через мой сокет, который должен в свою очередь вызватьNSXMLParser
делегаты.
Однако я не вижу ни одного из вызываемых делегатов, единственный вызываемый мной метод - это потоковый делегат.stream:handleEvent:
, Кажется, примеров Apple API или других разработчиков практически нет. Любые идеи о том, что я делаю неправильно или как использоватьinitWithStream:
правильно?
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