0

因此,我在阅读 Java 网站的渲染 html 源代码方面拥有丰富的经验。然而,我已经彻底研究了如何在 Objective-C 中做同样的事情,并且已经能够提出一个应该有效的解决方案,但它没有。这个想法是我想阅读每一行,例如:“view-source:www.apple.com”,我想逐行阅读该页面的结果。我不想要任何 Html 解析器等。这就是我所拥有的:

NSString *s = [NSString stringWithFormat:@"http://www.apple.com"];
NSURL *url = [NSURL URLWithString:s];

NSInputStream *iStream= [[NSInputStream alloc] initWithURL:url];

[iStream setDelegate:self];

[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                   forMode:NSDefaultRunLoopMode];

[iStream open];
NSLog(@"stream successfully opened");



NSInteger result;
uint8_t buffer[1024];
    while((result = [iStream read:buffer maxLength:1024]) != 0) {       
    if(result > 0) {
        NSLog(@"Buffer is %@",buffer);

        // buffer contains result bytes of data to be handled
    } else {
        NSLog(@"ERROR: %@",buffer);
        // The stream had an error. You can get an NSError object using [iStream streamError]
    }
    NSLog(@"end of while loop: %@",buffer);

}
// Either the stream ran out of data or there was an error


NSLog(@"Either the stream ran out of data or there was an error");

这可以正常运行和编译,但结果始终为 0。我再次进行了大量研究,但我不明白为什么结果为 0。感谢任何帮助。

4

2 回答 2

0

这个其他解决方案有效......

NSString *s = [NSString stringWithFormat:@"http://www.apple.com"];
NSURL *url = [NSURL URLWithString:s];


NSData *data = [NSData dataWithContentsOfURL:url];
NSString* newStr = [[NSString alloc] initWithData:data
                                         encoding:NSUTF8StringEncoding];
NSArray *arr= [newStr componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

虽然,我宁愿逐行阅读页面,因为这似乎效率低下 - 但我现在会解决这个问题,直到我能找到更好的答案。

于 2012-11-20T15:15:12.423 回答
0

您可能希望NSInputStream在此行之后检查您是否实际上是非零:

NSInputStream *iStream= [[NSInputStream alloc] initWithURL:url];

我看到的主要是你打开了一个NSInputStream但你从来没有用它发出任何 HTTP 请求。我认为您需要打开一个流对,NSOutputStream然后通过在NSInputStream.

这是一个说明性的代码片段:

#import <Foundation/Foundation.h>

@interface CCFStreamReader : NSObject <NSStreamDelegate>
- (void)readStream;
@end

@implementation CCFStreamReader {
    NSInputStream *_inputStream;
    NSOutputStream *_outputStream;
}
- (void)readStream {
    NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[url host], 80, &readStream, &writeStream);

    _inputStream = (__bridge_transfer NSInputStream *)readStream;
    _outputStream = (__bridge_transfer NSOutputStream *)writeStream;
    [_inputStream setDelegate:self];
    [_outputStream setDelegate:self];
    [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [_inputStream open];
    [_outputStream open];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
    NSLog(@"input stream = %@",_inputStream);
    printf("read something");
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent {
    printf("stream event: %d\n",(int)streamEvent);
    switch( streamEvent ) {
        case NSStreamEventHasSpaceAvailable:
        {
            if (aStream == _outputStream) {
                NSString *str = [NSString stringWithFormat:
                                  @"GET / HTTP/1.0\r\n\r\n"];
                const uint8_t *rawstring = (const uint8_t *)[str UTF8String];
                [_outputStream write:rawstring maxLength:str.length];
                [_outputStream close];
            }
            break;
        }
        case NSStreamEventHasBytesAvailable: {
            printf("Bytes available\n");
        }
    }

}

@end

int main(int argc, char *argv[]) {

    @autoreleasepool {
        CCFStreamReader *reader = [CCFStreamReader new];
        [reader readStream];
    }
}

通常的警告——这个片段很可能充满了错误。它并不打算成为一个完全开发的解决方案。例如,我实际上并没有从流中获取任何数据,等等。运行循环永远运行,等等。

最后,这假设您真的很想以这种方式处理 HTML,无论出于何种原因。

于 2012-11-19T19:48:30.897 回答