11

NSURLProtocol をオーバーライドし、特定の statusCode で HTTP 応答を返す必要があります。NSHTTPURLResponse には statusCode セッターがないため、次のようにオーバーライドしようとしました。

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse

    - (NSInteger)statusCode {
        return 200; //stub code
    }
@end

NSURLProtocol のオーバーライドされた startLoading メソッドは次のようになります。

-(void)startLoading
{   
   NSString *url = [[[self request] URL] absoluteString];
   if([url isEqualToString:SPECIFIC_URL]){
       MyURLResponse *response = [[MyURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://fakeUrl"]
       MIMEType:@"text/plain"
       expectedContentLength:0  textEncodingName:nil];

       [[self client] URLProtocol:self     
            didReceiveResponse:response 
            cacheStoragePolicy:NSURLCacheStorageNotAllowed];

       [[self client] URLProtocol:self didLoadData:[@"Fake response string"
            dataUsingEncoding:NSASCIIStringEncoding]];

       [[self client] URLProtocolDidFinishLoading:self];                

       [response release];

    }
    else{   
        [NSURLConnection connectionWithRequest:[self request] delegate:self];   
    }
}

しかし、このアプローチは機能しません。NSURLProtocol で作成された応答は、Web ページ上で常に statusCode = 0 になります。同時に、NSURLConnection によってネットワークから返される応答には、通常の予想される statusCodes があります。

作成された NSURLResponse に対して statusCode を明示的に設定する方法について、誰でもアイデアを手伝ってもらえますか? ありがとう。

4

3 に答える 3

10

これがより良い解決策です。

iOS 5.0 以降では、プライベート API やオーバーロードでクレイジーなことをする必要はNSHTTPURLResponseもうありません。

独自のステータス コードとヘッダーを使用してを作成するNSHTTPUTLResponseには、次のように簡単に使用できます。

initWithURL:statusCode:HTTPVersion:headerFields:

これは、生成されたドキュメントには記載されていませんが、実際にはNSURLResponse.hヘッダー ファイルに存在し、OS X 10.7 および iOS 5.0 で使用できるパブリック API としてマークされています。

NSURLProtocolまた、トリックを使用してXMLHTTPRequestから呼び出しを行う場合は、ヘッダーを適切UIWebViewに設定する必要があることに注意してください。Access-Control-Allow-Originそうしないと、XMLHTTPRequestセキュリティが作動しNSURLProtocol、リクエストを受信して​​処理しても、応答を返すことができなくなります。

于 2012-03-02T18:50:23.150 に答える
4

次のコードを使用して、カスタム init メソッドを実装しました。

    NSInteger statusCode = 200;
    id headerFields = nil;
    double requestTime = 1;

    SEL selector = NSSelectorFromString(@"initWithURL:statusCode:headerFields:requestTime:");
    NSMethodSignature *signature = [self methodSignatureForSelector:selector];

    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature];
    [inv setTarget:self];
    [inv setSelector:selector];
    [inv setArgument:&URL atIndex:2];
    [inv setArgument:&statusCode atIndex:3];
    [inv setArgument:&headerFields atIndex:4];
    [inv setArgument:&requestTime atIndex:5];

    [inv invoke];
于 2011-08-08T07:41:00.550 に答える
3

URLResponse からのみステータス コードを取得します。明示的に設定する必要はありません:-

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];  

    NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"ResponseString:%@",responseString);

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    int statusCode = [httpResponse statusCode];
    NSLog(@"%d",statusCode);
于 2010-12-08T06:49:26.753 に答える