11

我覆盖了 NSURLProtocol 并且需要返回带有特定状态码的 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 中创建的响应在网页上总是带有 statusCode = 0。同时,由 NSURLConnection 从网络返回的响应具有正常的预期状态码。

任何人都可以请教如何为创建的 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技巧从 a 进行XMLHTTPRequest调用UIWebView,则需要Access-Control-Allow-Origin适当地设置标头。否则,XMLHTTPRequest安全性会启动,即使您NSURLProtocol将接收并处理请求,您也无法发回响应。

于 2012-03-02T18:50:23.150 回答
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];
于 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 回答