我正在尝试为NSURLProtocol创建一个子类。但是,我注意到,当我注册我的子类时,我似乎失去了缓存功能,即使它不应该做任何事情。例如,如果我在不注册子类的情况下多次[NSURLConnection sendSynchronousRequest ...]到同一个URL,它只执行一个实际的http请求。注册此子类后,它每次都会执行网络请求。
这是我的代码:
@interface CustomURLProtocol : NSURLProtocol
@property (nonatomic, strong) NSURLConnection *connection;
@end
@implementation CustomURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
return [[[request URL] scheme] isEqualToString:@"http"] &&
[NSURLProtocol propertyForKey:@"tagged" inRequest:request] == nil;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}
- (void)startLoading {
NSMutableURLRequest *newRequest = [self.request mutableCopy];
[NSURLProtocol setProperty:@YES forKey:@"tagged" inRequest:newRequest];
self.connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
}
- (void)stopLoading {
[self.connection cancel];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[[self client] URLProtocol:self didLoadData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[self client] URLProtocol:self didFailWithError:error];
self.connection = nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:[[self request] cachePolicy]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[[self client] URLProtocolDidFinishLoading:self];
self.connection = nil;
}
@end
答案 0 :(得分:1)
这里的问题不是我的预期。真正的问题是重定向没有得到正确处理,因为以下代码不存在:
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
[[self client] URLProtocol:self wasRedirectedToRequest:request redirectResponse:response];
return request;
}
如果没有此代码,重定向不会被缓存,因此请求对重定向的网址(如wikipedia.com)的顺序请求每次都会导致重定向。
答案 1 :(得分:1)
我认为您添加的行只是跳过您的自定义NSURLProtocol。添加此方法后,是否还在调用那些connectionDelegate方法?
更新:终于弄明白了。这就是原因。将此部件添加到startLoading后,我将其工作。
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request];
if (cachedResponse) {
[self connection:nil didReceiveResponse:[cachedResponse response]];
[self connection:nil didReceiveData:[cachedResponse data]];
[self connectionDidFinishLoading:nil];
} else {
_connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
}