在对canInitWithRequest的YES响应之后,NSURLProtocol不会被要求加载
我正在注册一个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
传递给canInitWithRequest
,属性已经被剥离,然后,即使我们回应YES
我们也从未真正得到了入口 - 页面完全返回到UIWebView
,没有随后的资产请求。 这是请求在创建时的样子:
NSURLRequest *request = [NSURLRequest requestWithURL:myURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[self.webView loadRequest:request];
为什么,当我说我的协议可以处理请求时,是不是有机会这么做? 我的猜测是答案在于UIWebView本身的实现。 如果我真的希望我的协议成为加载的负责实体,如何解决此问题的任何想法?
我能够通过缓存破坏UIWebView缓存来解决这个问题,而不是破坏NSURLCache。
canonicalRequestForRequest:
的密钥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;
}
我的init代码如下所示:
- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client
{
self = [super initWithRequest:[MYURLProtocol canonicalRequestForRequest:request] cachedResponse:cachedResponse client:client];
return self;
}
我不喜欢我必须这样做,但我终于得到了我想要的行为。 希望它能帮助那里的人。
*** 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];
链接地址: http://www.djcxy.com/p/34843.html
上一篇: NSURLProtocol isn't asked to load after YES response to canInitWithRequest
下一篇: Loading resources from relative paths through NSURLProtocol subclass