2010-12-08 10 views
9

NSURLProtocolをオーバーライドし、特定のstatusCodeでHTTP応答を返す必要があります。 NSHTTPURLResponseはstatusCodeをセッターを持っていないので、私はそれを上書きしようとした:NSURLResponseで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によってネットワークから返される応答は、通常、正常なexpected statusCodesを持ちます。

誰でも作成したNSURLResponseに対してstatusCodeを明示的に設定する方法を教えてください。 〜

+0

この問題の解決方法をお探しですか? – TomSwift

答えて

4

:ここ

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]; 
+0

ありがとうございます。私はあなたのソリューションを試して、statusCode 200を得ました。これは私の問題を解決し、私は正確にステータス200が必要でした。しかし、私は任意のステータスを設定することに失敗しました:statusCodeはNSInvocationのstatusCode ?とにかく、私はこれを答え、thnxとマークします。 – okonov

+0

ちょうど試みました - 私は任意のステータスコードを設定することができます(私は215を設定します)。そしてそれはウェブページでも同じです - 215。 –

4

U URLResponseからステータスコードを取得します。必要はありませ明示的に設定しないように: -

私は、次のコードを使用して、カスタムのinitメソッドを実装しました
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); 
+0

ありがとうございます。しかし、ネットワークからhttp応答のstatusCodeを取得する必要はありません。 NSURLResponseを自分で作成して、オーバーライドされたNSURLProtocolの中に返すようにして、レスポンスのstatusCodeを設定する必要があります。 – okonov

9

がよりよい解決策です。

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

は、あなたが今簡単に使用することができ、あなた自身のステータスコードとヘッダを持つ NSHTTPUTLResponseを作成するには:生成されたドキュメントに記載されていない

initWithURL:statusCode:HTTPVersion:headerFields: 

しかしNSURLResponse.hヘッダファイル中に実際に存在とありますOS X 10.7およびiOS 5.0で公開されている公開APIとしてマークされています。

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

関連する問題