4

我正在尝试为 NSURLProtocol 创建一个子类。但是,我注意到当我注册我的子类时,我似乎失去了缓存功能,即使它不应该做任何事情。例如,如果我对同一个 URL 多次执行 [NSURLConnection sendSynchronousRequest...] 而不注册子类,它只会执行一个实际的 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
4

2 回答 2

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];
    }
于 2014-06-04T20:49:30.777 回答
1

这里的问题不是我所期望的。真正的问题是没有正确处理重定向,因为以下代码不存在:

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
  [[self client] URLProtocol:self wasRedirectedToRequest:request redirectResponse:response];
  return request;
}

如果没有此代码,则不会缓存重定向,因此请求因此对重定向 URL(如 wikipedia.com)的连续请求会导致每次重定向。

于 2013-09-30T00:24:12.583 回答