导致自定义NSURLProtocol
我正在NSURLProtocol
以拦截HTTP请求。
这是自定义的NSURLProtocol
类。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if (NSOrderedSame != [request.URL.scheme caseInsensitiveCompare:@"http"] &&
NSOrderedSame != [request.URL.scheme caseInsensitiveCompare:@"https"]) {
return NO;
}
if ([NSURLProtocol propertyForKey:kURLProtocolRequestHandledKey inRequest:request] ) {
return NO;
}
return YES;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
NSMutableURLRequest *mutableReqeust = [request mutableCopy];
[NSURLProtocol setProperty:@YES forKey:kURLProtocolRequestHandledKey inRequest:mutableReqeust];
return [mutableReqeust copy];
}
- (void)startLoading {
self.startDate = [NSDate date];
self.data = [NSMutableData data];
self.error = nil;
self.connection = [[NSURLConnection alloc] initWithRequest:[[self class] canonicalRequestForRequest:self.request] delegate:self startImmediately:YES];
}
- (void)stopLoading {
[self.connection cancel];
}
#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[self client] URLProtocol:self didFailWithError:error];
self.error = error;
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection {
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[self client] URLProtocol:self didReceiveAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[self client] URLProtocol:self didCancelAuthenticationChallenge:challenge];
}
#pragma mark - NSURLConnectionDataDelegate
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
if (response != nil){
_response = response;
NSMutableURLRequest *redirect = [request mutableCopy];
redirect.URL = request.URL;
[NSURLProtocol setProperty:@NO forKey:kURLProtocolRequestHandledKey inRequest:redirect];
[[self client] URLProtocol:self wasRedirectedToRequest:redirect redirectResponse:response];
return redirect;
}
return request;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
_response = response;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[[self client] URLProtocol:self didLoadData:data];
[self.data appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return cachedResponse;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[[self client] URLProtocolDidFinishLoading:self];
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
}
我添加一个UIWebView
作为子视图,然后加载一个URL http://ln.clientaccess.10086.cn/shop/optical/Appointment?channel=007&PHONE_NUM=18240235054&AREA_CODE=240&key=4A35774433BA79EB950EDE4B5C4D7121
,控制器被解散后,APP被冻结即使我在调用webView之前先调用- stopLoading
,然后再解除它。
这是线程堆栈:
我不认为你想修改canonicalRequest中的请求 - 单独留下。 您确实想在startLoading中对其进行修改,并在NSURLConnection的新调用中使用修改的请求,以便您的协议在该调用期间不再处理它。
第二件事是重定向实现可能是错误的 - 该方法在两种情况下被调用; 一次发送请求时(并且重定向为零); 你想在这种情况下返回请求(你这样做)。 第二个是当你实际得到重定向时; 你想调用客户端(你是),但是你想返回零,以便让客户端实际处理重定向(否则非零返回可以表示重定向已被处理)。
我不确定其中哪一个会导致这个问题,但他们是不同的。
我唯一看到的不同于我实施的其他事情是开始立即:YES。 这是默认的,所以这不应该成为问题。 也许尝试避免缓存,看看是否有帮助,如果以上都没有。 或者确保在dealloc的连接上调用-cancel。
使用startImmediately:NO
而不是startImmediately:YES
会解决这个问题。
if (currentRunLoop && [currentRunLoop currentMode]) {
self.connection = [[NSURLConnection alloc] initWithRequest:[[self class] canonicalRequestForRequest:self.request] delegate:self startImmediately:NO];
[self.connection scheduleInRunLoop:currentRunLoop forMode:[[NSRunLoop currentRunLoop] currentMode]];
[self.connection start];
} else {
self.connection = [[NSURLConnection alloc] initWithRequest:[[self class] canonicalRequestForRequest:self.request] delegate:self startImmediately:YES];
}
它是有线的。 请问有人会告诉我为什么?
链接地址: http://www.djcxy.com/p/34791.html上一篇: Custom NSURLProtocol caused
下一篇: NSURLProtocol + UIWebView + certain domains = app UI frozen