0

そのため、JavaでWebサイトのレンダリングされたhtmlソースコードを読んだ豊富な経験があります。しかし、Objective-Cでまったく同じことを行う方法について徹底的に調査し、機能するはずのソリューションを考え出すことができましたが、そうではありません。たとえば、「view-source:www.apple.com」のように、各行を読みたいという考えです。そのページの結果を1行ずつ読みたいのです。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

NSInputStreamこの行の後で、自分が実際にnilでないかどうかを確認することをお勧めします。

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

主に私が見ているのは、あなたがを開いたNSInputStreamが、それを使ってHTTPリクエストを行うことは決してないということです。NSOutputStreamストリームペアを開き、HTTP GETリクエストを送信してから、をリッスンする必要があると思います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 に答える
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]];

ただし、これは非効率的であると思われるため、ページを1行ずつ読んでおくほうがよいでしょう。しかし、より良い答えが見つかるまで、今のところこれで解決します。

于 2012-11-20T15:15:12.423 に答える