我重写NSURLProtocol并需要返回具有特定statusCode的HTTP响应。 NSHTTPURLResponse没有statusCode setter,所以我尝试用以下方法覆盖它:
@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从网络返回的响应具有正常的预期statusCodes。
任何人都可以请教如何为创建的NSURLResponse显式设置statusCode吗?感谢名单。
答案 0 :(得分:9)
这是一个更好的解决方案。
在iOS 5.0及更高版本中,您不必再使用私有API或重载NSHTTPURLResponse
做任何疯狂的事情。
要使用您自己的状态代码和标题创建NSHTTPUTLResponse
,您现在只需使用:
initWithURL:statusCode:HTTPVersion:headerFields:
生成的文档中未记录,但 实际存在于NSURLResponse.h
头文件中,并且还标记为OS X 10.7和iOS 5.0上提供的公共API。< / p>
另请注意,如果您使用NSURLProtocol
技巧从XMLHTTPRequest
拨打UIWebView
来电,那么您需要正确设置Access-Control-Allow-Origin
标头。否则,XMLHTTPRequest
安全性会启动,即使您的NSURLProtocol
将收到并处理请求,您也无法发回回复。
答案 1 :(得分:4)
您只能从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);
答案 2 :(得分: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];