我正在注册NSURLProtocol的实现来对某些URL请求进行一些自定义处理(我通过在它们上设置属性来标记这些请求)。这些URL请求来自UIWebView的加载方法。
我发现第2步和第5步之间存在明显不同的行为。我的NSURLProtocol实现管理缓存数据,旨在处理请求。如果我在请求中没有检测到我的属性,我会再次检查特定的URL(用于调试)。无论哪种情况,canInitWithRequest
都会返回YES
:
发布后首次加载:
2014-10-15 11:37:11.403 MYApp[5813:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x15ebbb40> https://example.com/
2014-10-15 11:37:11.404 MYApp[5813:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x15dc8da0> https://example.com/
2014-10-15 11:37:11.409 MYApp[5813:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x15ee5ef0> https://example.com/
2014-10-15 11:37:11.409 MYApp[5813:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x15ee6240> https://example.com/
2014-10-15 11:37:11.410 MYApp[5813:60b] MYURLProtocol initWithRequest:cachedResponse:client: Request: https://example.com/
2014-10-15 11:37:11.411 MYApp[5813:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x15ee69d0> https://example.com/
2014-10-15 11:37:11.415 MYApp[5813:9c07] MYURLProtocol startLoading Loading <0x15ee6240> https://example.com/
... A bunch of loading of assets occurs (cached responses) ...
2014-10-15 11:37:12.497 MYApp[5813:60b] MyWebViewController webViewDidFinishLoad: Finished loading
其他人已经指出,协议有多个关于同一资产的调用,这不是一个问题,尽管有趣的是要注意每次使用新对象调用它时,它是第4个( 4)传递给startLoading
的对象。不过,这里没有真正的担忧。
后续加载:
2014-10-15 11:11:27.466 MYApp[5782:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x1727c310> https://example.com/
2014-10-15 11:11:27.467 MYApp[5782:60b] MYURLProtocol canInitWithRequest: Matched property in request: <0x145b1d90> https://example.com/
2014-10-15 11:11:27.488 MYApp[5782:560f] MYURLProtocol canInitWithRequest: Matched URL in request: <0x17266060> https://example.com/
2014-10-15 11:11:27.669 MYApp[5782:60b] MYWebViewController webViewDidFinishLoad: Finished loading
在我看来,这是出乎意料的行为。看来,第三次将属性传递给canInitWithRequest
时,属性已从请求中删除,然后,即使我们回复YES
,我们也从未真正进入过 - 该页面只是返回到完整的UIWebView
,没有后续的资产请求。以下是创建请求时的样子:
NSURLRequest *request = [NSURLRequest requestWithURL:myURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[self.webView loadRequest:request];
为什么,当我说我的协议可以处理请求时,是否没有机会这样做?我的猜测是答案在于UIWebView本身的实现。如果我真的希望我的协议成为负责的实体加载,有关如何解决这个问题的任何想法吗?
答案 0 :(得分:1)
*** Way to clear the cache of webview **********
Follow this code:
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
答案 1 :(得分:0)
我能够通过缓存清除UIWebView缓存来解决此问题,同时不破坏NSURLCache。
canonicalRequestForRequest:
和initWithRequest:cachedResponse:client
我的剥离代码看起来像这样(可能有一种更简洁的方法来剥离参数,但这有效):
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
NSURLRequest *canonicalRequest = request;
BOOL myProtocolRequest = [[NSURLProtocol propertyForKey:kMYProtocolRequest inRequest:request] boolValue];
if (myProtocolRequest)
{
NSMutableURLRequest *mutableRequest = [request mutableCopyWorkaround];
NSString *originalURLString = mutableRequest.URL.absoluteString;
NSString *regexString = [NSString stringWithFormat:@"(?:[?&])(key=[[:digit:]]{%d}&*)", kMYKeyLength];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:0 error:0];
NSTextCheckingResult *result = [regex firstMatchInString:originalURLString options:0 range:NSMakeRange(0, originalURLString.length)];
if (result.numberOfRanges > 1)
{
NSRange keyRange = [result rangeAtIndex:1];
NSLog(@"Removing '%@' from request", [originalURLString substringWithRange:keyRange]);
NSString *replacementURLString = [originalURLString stringByReplacingCharactersInRange:keyRange withString:@""];
mutableRequest.URL = [NSURL URLWithString:replacementURLString];
canonicalRequest = mutableRequest;
}
}
return canonicalRequest;
}
我的初始化代码如下:
- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client
{
self = [super initWithRequest:[MYURLProtocol canonicalRequestForRequest:request] cachedResponse:cachedResponse client:client];
return self;
}
我不喜欢我必须这样做,但我终于得到了我想要的行为。希望它可以帮助那里的人。