2013-09-28 3 views
4

NSURLProtocol에 대한 하위 클래스를 만들려고합니다. 그러나 하위 클래스를 등록 할 때 캐싱 기능을 잃어버린 것처럼 보입니다. 예를 들어, 하위 클래스를 등록하지 않고 동일한 URL에 [NSURLConnection sendSynchronousRequest ...]를 여러 번 수행하면 실제 HTTP 요청을 한 번만 수행합니다. 이 서브 클래스를 등록하면 매번 네트워크 요청을 수행합니다.캐싱이 사용자 지정 NSURLProtocol과 작동하지 않습니다.

@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 

답변

1

문제는 여기에 내가 무엇을 기대하지 않았다 :

여기 내 코드입니다.

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

가 리디렉션 결과 wikipedia.com 같은 리디렉션 된 URL에 대한 요청 때문에 순차적 인 요청을 수 있도록 캐시되지되지 않은 : 진짜 문제는 다음과 같은 코드가없는 이후 리디렉션이 제대로 처리되지 있다고했다 매번 리디렉션됩니다.

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]; 
    } 
+1

가능한 이유는 사용자 지정 NSURLProtocol이 http로 처리되지 않는다고 생각합니다. 그런 다음 요청에 의해 전송 된 캐시 정책은 기본적으로 NSURLRequestUseProtocolCachePolicy이며 URL로드 시스템은이를 캐시하는 방법을 모르기 때문에 모든 캐시를 삭제합니다. – jqyao

관련 문제