iOS 11 WKWebView問題のまとめ
問題の説明:
iOS 9とiOS 10はWKWebViewでURLをロードしても大丈夫です。iOS 11は空白です。
NSMutable URLRequestを使っているかもしれませんが、iOS 11はNSMutureble Lrequestをサポートしていないようです。UICWebViewを使ってもWKWebViewを使ってもNSMutureble LRequestはサポートされていません。
解決方法の参考
小さいTips:
いくつかのスタック情報を取得するために、正確でハードな位置決め問題があります。
1、システムはこの方法が何度も実行されていると判断し、主にdecision Handler()が何度も実行されているかを見る。
2、if判断ではdecisionhandler()が実行されますので、最後の行のコードもdecisionhandler()を実行します。そしてself.realDelegateではdecisionhandler()も実行されます。これはdecision Handler()というhandlerを複数回実行させる可能性があります。
問題を解決する方向はコードを修正してWKWebView単一LoadRequestを一回だけ調整するということです。
以下のように修正します
問題3説明:iOS 11 WKWebviewの取得高さは不正確です。
この問題に出会った時、約64ピクセル離れていたことに気づき、tablewとcollection Viewを連想しました。
したがって解決方法は以下の通りである。
iOS 9とiOS 10はWKWebViewでURLをロードしても大丈夫です。iOS 11は空白です。
NSMutable URLRequestを使っているかもしれませんが、iOS 11はNSMutureble Lrequestをサポートしていないようです。UICWebViewを使ってもWKWebViewを使ってもNSMutureble LRequestはサポートされていません。
解決方法の参考
if #available(iOS 11, *) {
let request = NSURLRequest.init(url: URL.init(string: urlStr)!)
self.wkWebView.load(request as URLRequest)
}else{
let request = NSMutableURLRequest.init(url: URL.init(string: urlStr)!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 60)
request.httpMethod = "GET"
request.httpBody = ("token=" + tokenValue()).data(using: String.Encoding.utf8)
self.wkWebView.load(request as URLRequest)
}
問題2:iPhone Xのシミュレータを使ってHybridプロジェクトに入ると、入ると潰れてしまい、情報が少ないのがかわいそうです。libc++abi.dylib: terminating with uncaught exception of type NSException
これでは間違いなくバグを特定できませんが、全体のブレークポイントはやはり情報を与えました。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSString *requestString = navigationAction.request.URL.absoluteString;
// 、 appstore
UIApplication *app = [UIApplication sharedApplication];
NSURL *url = [navigationAction.request URL];
//
//
if ([url.absoluteString containsString:@"itunes.apple.com"])
{
if ([app canOpenURL:url])
{
[app openURL:url];
decisionHandler(WKNavigationActionPolicyCancel);
}
}
if ([requestString hasPrefix:@"easy-js:"]) {
[self handleRequestString:requestString webView:(EasyJSWebView *)webView.superview];
decisionHandler(WKNavigationActionPolicyCancel);
}
if ([self.realDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)])
{
[self.realDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
}
decisionHandler(WKNavigationActionPolicyAllow);//
}
なぜここで崩れたのかまだ分かりません。前はずっと大丈夫でしたか?小さいTips:
いくつかのスタック情報を取得するために、正確でハードな位置決め問題があります。
int main(int argc, char * argv[]) {
@try {
@autoreleasepool
{
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
@catch (NSException* exception)
{
NSDebugLog(@"Exception=%@
Stack Trace:%@", exception, [exception callStackSymbols]);
}
}
最終的に一つのキーのエラーを得ました。
Completion handler passed to -[WKPrivateNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once
WKWebViewのこの代理方法は何回も呼び出されました。
if ([requestString hasPrefix:@"easy-js:"]) {
[self handleRequestString:requestString webView:(EasyJSWebView *)webView.superview];
decisionHandler(WKNavigationActionPolicyCancel);
}
if ([self.realDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)])
{
[self.realDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
}
decisionHandler(WKNavigationActionPolicyAllow);//
何度も呼び出された理由を簡単に分析します。1、システムはこの方法が何度も実行されていると判断し、主にdecision Handler()が何度も実行されているかを見る。
2、if判断ではdecisionhandler()が実行されますので、最後の行のコードもdecisionhandler()を実行します。そしてself.realDelegateではdecisionhandler()も実行されます。これはdecision Handler()というhandlerを複数回実行させる可能性があります。
問題を解決する方向はコードを修正してWKWebView単一LoadRequestを一回だけ調整するということです。
以下のように修正します
if ([requestString hasPrefix:@"easy-js:"]) {
[self handleRequestString:requestString webView:(EasyJSWebView *)webView.superview];
decisionHandler(WKNavigationActionPolicyCancel);
}
else if ([self.realDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)])
{
[self.realDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
すなわち、単一LoadRequestが一回だけ実行することを保証しました。decision Handler()問題3説明:iOS 11 WKWebviewの取得高さは不正確です。
この問題に出会った時、約64ピクセル離れていたことに気づき、tablewとcollection Viewを連想しました。
したがって解決方法は以下の通りである。
if (@available(iOS 11.0, *)) {
_webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
_webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
_webView.scrollView.scrollIndicatorInsets = _webView.scrollView.contentInset;
}