iOS 11 WKWebView問題のまとめ

4919 ワード

問題の説明:
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;
 }