ChenYilong / iOS11AdaptationTips

for iOS11 in [ObjC, Swift, English, 中文] {...} -- iOS11适配系列教程
MIT License
485 stars 47 forks source link

Deal With WKWebView DNS pollution problem in iOS11 #16

Open ChenYilong opened 7 years ago

ChenYilong commented 7 years ago

iOS 11 WKWebView provides APIs which work like NSURLProtocol in UIWebView, it's useful to WKWebView DNS pollution problem.

New API -[WKWebViewConfiguration setURLSchemeHandler:forURLScheme:],provide WKURLSchemeHandler to handle the request with your network tool.

Reference: Apple API Doc

ChenYilong commented 7 years ago

unable to handle http and https

 [_webView.configuration setURLSchemeHandler:self forURLScheme:@"http"];
 [_webView.configuration setURLSchemeHandler:self forURLScheme:@"https"];
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ''http' is a URL scheme that WKWebView handles natively'

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ''https' is a URL scheme that WKWebView handles natively'

same with ftp:// file:// data://.

reason

Reference: Source Code

- (void)setURLSchemeHandler:(id <WKURLSchemeHandler>)urlSchemeHandler forURLScheme:(NSString *)urlScheme
{
    auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });

    if ([WKWebView handlesURLScheme:urlScheme])
        [NSException raise:NSInvalidArgumentException format:@"'%@' is a URL scheme that WKWebView handles natively", urlScheme];

    auto canonicalScheme = WebCore::URLParser::maybeCanonicalizeScheme(urlScheme);
    if (!canonicalScheme)
        [NSException raise:NSInvalidArgumentException format:@"'%@' is not a valid URL scheme", urlScheme];

    if ([urlSchemeHandlers objectForKey:(NSString *)canonicalScheme.value()])
        [NSException raise:NSInvalidArgumentException format:@"URL scheme '%@' already has a registered URL scheme handler", urlScheme];

    [urlSchemeHandlers setObject:urlSchemeHandler forKey:(NSString *)canonicalScheme.value()];
}

why?

the new API function is not for request handling, the function looks like this:

//OC register scheme for JS to invoke
[[_webView configuration].userContentController addScriptMessageHandler:self name:@"closeMe"];

//OC operation after JS method invoked
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    NSLog(@"JS invoke  %@ method,paramers is %@",message.name,message.body);
}

//JS invoke:
    window.webkit.messageHandlers.closeMe.postMessage(null);

the feature is more like WebViewJavascriptBridge , rather than NSURLProtocol.

ChenYilong commented 7 years ago

So can the new API -[WKWebViewConfiguration setURLSchemeHandler:forURLScheme:] deal With WKWebView DNS pollution problem in iOS11?

The answer is CANNOT.

ChenYilong commented 7 years ago

iOS11 new API WKHTTPCookieStore can handle the WKWebView Cookie Infomation.

new feature:

  WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;
   //get cookies
    [cookieStroe getAllCookies:^(NSArray<NSHTTPCookie *> * _Nonnull cookies) {
        NSLog(@"All cookies %@",cookies);
    }];

    //set cookie
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSHTTPCookieName] = @"userid";
    dict[NSHTTPCookieValue] = @"123";
    dict[NSHTTPCookieDomain] = @"xxxx.com";
    dict[NSHTTPCookiePath] = @"/";

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:dict];
    [cookieStroe setCookie:cookie completionHandler:^{
        NSLog(@"set cookie");
    }];

    //delete cookie
    [cookieStroe deleteCookie:cookie completionHandler:^{
        NSLog(@"delete cookie");
    }];
JeroldLiu777 commented 7 years ago

阿西吧 那不是僵硬了 不能处理http和https请求,WKWebView在NSURLProtocol下问题多啊

ChenYilong commented 7 years ago

@lucifer717 参考这里:https://github.com/ChenYilong/iOSBlog/issues/11

JeroldLiu777 commented 7 years ago

@ChenYilong OK thx