Xcode 9 GM-以前のバージョンではWKWebView NSCodingサポートが壊れていました


155

Xcode 9 GMでこのエラーを修正する方法を誰かが知っていますか?私はXcode 8.3で作成されたアプリに取り組んでいます。展開ターゲットはiOS 9.3であり、この問題を以前に経験したことがありません。ここやAppleフォーラムではまだ情報が見つかりません:(

編集:このエラーは、WKWebViewをインターフェイスビルダーに配置したときに発生しました。プログラムで使用した場合ではありません。

画像WKWebViewエラーを参照してください

編集2:まあ、それは最終的にはバグではありません。この動作の詳細については、以下のクインの回答を参照してください。説明してくれてありがとう。


1
以下の私の答えを参照してください。これはXcode 9のバグではありません。このビルドエラーなしで、あなたの代わりに-initWithCoderでクラッシュになるだろう:前のiOS 11の実行時に
クインテイラー

1
私はちょうど11に私のデプロイメント・ターゲットを変更

回答:


160

このエラーは正しい動作であり、Xcode 9のバグではありません。WKWebViewはiOS 8で導入されました-[WKWebView initWithCoder:]が、実行時に常にクラッシュし、Interface Builder内での構成を妨げるiOS 11でのみ修正されたバグがありました。

https://bugs.webkit.org/show_bug.cgi?id=137160

開発者が実行時に壊れるようなIBでのビルドを許可するのではなく、ビルドエラーです。iOS 11が最近リリースされたばかりなので、これは不便な制限ですが、他に良い選択肢はありません。

@ fahad-ashrafが彼の回答ですでに説明しているように、古い展開ターゲットの回避策は、コードにWKWebViewを追加し続けることです。

https://developer.apple.com/documentation/webkit/wkwebview


3
こんにちはクイン、私はAppleで働いている人だと思います:-)私はそれについてのバグレポートも見つけました:lists.webkit.org/pipermail/webkit-unassigned/2014-September/…新しいことに本当に驚いていますそのような振る舞いに遭遇したとき、開発者は私のようなものです。再度、感謝します。
Mehdi Chennoufi 2017年

ありがとうございました!重宝しました。
ssowri1

2
ios10でもサポートしたい場合はどうしますか?私のアプリではiOS 10もサポートする必要があります。この問題を解決するにはどうすればよいですか?
Kalikanth040494

なぜAppleがiOS 11までフィックスを見つけ出すのにそれが必要だったのか気になるだけなのか?
エマン

96

これはXcode 9のバグのようで、ベータ版にも存在していました。ストーリーボードを介してWKWebViewを作成している場合にのみ、ビルドエラーが発生します。対応するViewControllerクラスファイルにプログラムでWKWebViewを作成すると、iOS 11より前のバージョンのiOSでビルドできるはずです。これを実現する方法について、AppleのWebサイトで提供されているアプローチを次に示します。

import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {

    var webView: WKWebView!

    override func loadView() {
        super.loadView()
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string: "https://www.apple.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }}

これで、通常どおりにWKWebView機能を実装できるはずです。

ソース:https : //developer.apple.com/documentation/webkit/wkwebview


5
忘れないでくださいsuper.loadView()
albirrojo7 2018年

super.loadView()最初にある必要があります。それがなければ、何も表示されません。
マカレル2018年

こんにちは:)、この制約をwebviewNavigationBarの下に設定する方法を知っていますか?このソリューションは機能しますが、画面全体をカバーします。
Abed Naseri

@AbedNaseri制約を設定する必要はないと思います...ストーリーボードをインスタンス化してから、self.navigationController?.pushViewController(youVC、animated:true)をインスタンス化できます。
xhinoda

58

さらに他のコンポーネントでカスタムUIViewControllerを実現したい場合は、次のようなストーリーボードを使用して「コンテナ」を作成できますwebViewContainer

import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
    @IBOutlet weak var webViewContainer: UIView!
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let webConfiguration = WKWebViewConfiguration()
        let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: 0.0, height: self.webViewContainer.frame.size.height))
        self.webView = WKWebView (frame: customFrame , configuration: webConfiguration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        self.webViewContainer.addSubview(webView)
        webView.topAnchor.constraint(equalTo: webViewContainer.topAnchor).isActive = true
        webView.rightAnchor.constraint(equalTo: webViewContainer.rightAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: webViewContainer.leftAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: webViewContainer.bottomAnchor).isActive = true
        webView.heightAnchor.constraint(equalTo: webViewContainer.heightAnchor).isActive = true
        webView.uiDelegate = self

        let myURL = URL(string: "https://www.apple.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }

本当にありがとう、本当に助かります。これはAppleが知っているバグです
セバスチャンREMY 2017年

1
働きました!iOS 11およびswift 4.1でテスト済み
Alwin

2
エラーが発生した[LayoutConstraints] Unable to simultaneously satisfy constraints場合は、その行を忘れないでくださいwebView.translatesAutoresizingMaskIntoConstraints = false。trueに設定したままにwebViewすると、プログラムで追加した制約と競合する制約のセット全体が自動的に作成されます。 Apple Docs
mogelbuster 2018年

51

古いターゲットからiOS 11.0に移動してもまだこのエラーが発生する場合は、以下の解決策を使用してください。

  1. ストーリーボード(Main.storyboard)に移動し、任意のシーンをクリックします。
  2. Xcodeの右側のプロパティウィンドウである「ファイルインスペクター」を選択します
  3. ビルドの値」の値を「iOS 11.0以降」に変更します」に変更します。
  4. コンパイルしてビルド

ここに画像の説明を入力してください


2
@VyachaslavGerchicov:私はあなたのことは知りませんが、業界では、より新しい技術に変換する必要がある古いプロジェクトを持っています。多くの人が同じ問題に直面しています。回答ですでに「古いターゲットから移動した場合」と述べました。1つのケースだけを考えないでください。
カンパイ

1
これは、この迷惑なIB設定を指摘してくれてありがとう。警告はすぐになくなりました。実際には、これはより実用的で、受け入れられるべき答えだと思います。@Kampaiに同意します。実際には、Appleが基本的なフレームワークを変更し続けているため、iOSの新しいバージョンへの移行を余儀なくされています
infinity_coding7

iOS 10.xアプリでシミュレーターを実行しているときにそれを実行すると、クラッシュします。
ラミス

@Ramis:私はiOS 10のためにそれをしていました、私はアプリのクラッシュを得ることはありませんでした、クラッシュログは何でしたか?
カンパイ

1
この問題を修正するための最も簡単な解決策。ありがとう!
ジェリーチョン

18

私は同じ問題に直面しましたが、プログラムでWKWebViewを追加する場合は対処することができます。

  1. ストーリーボードで作成したいデザインをすべて行いますが、WKWebViewの余地を残し、その領域にビューをドラッグアンドドロップして、webViewContainerという名前を付け、これら2つのプロパティを宣言します。

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
  2. 次に、次のようにwebViewを作成して追加します。

    -(instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        self.webView = [self createWebView];
        self = [super initWithCoder:aDecoder];
        return self;
    }

    createWebView関数は、

    -(WKWebView *)createWebView
    {
         WKWebViewConfiguration *configuration = 
                   [[WKWebViewConfiguration alloc] init];
         return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
  3. 次のように、新しく作成したこのwebViewをcontainerViewに追加します。

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
  4. 最後に、次のようにURLをロードします。

    -(void)webViewLoadUrl:(NSString *)stringUrl
    {
         NSURL *url = [NSURL URLWithString:stringUrl];
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         [self.webView loadRequest:request];
    }

これを読んでくれてありがとう。


3

WebKitはiOS 8で導入されましたが、ランタイムクラッシュの原因となるエラーでリリースされました。Xcode9 /10を使用している場合、プロジェクト構成サポートはiOS 11よりも少なく、インターフェイスビルダーを使用してWKWebViewを追加しようとしています。Xcodeはすぐにコンパイル時エラーを表示します。

iOS 11.0より前のWKWebView(以前のバージョンではNSCodingサポートが壊れていました)

WKWebViewはiOS 8で導入されましたが、– [WKWebView initWithCoder:]にバグがあり、iOS 11でのみ修正されました。

ここに画像の説明を入力してください

解決策は、コードを介してWKWebViewを追加する必要があることです(iOS 11以下をサポートしている場合のみ)。それは実際には奇妙に聞こえます。

別の解決策は、オプションのInterface Builder Document BuildsをiOS 11以降に変更することです(古いターゲットからiOS 11に移行しても同じエラーが発生する場合)。


1

// Swiftの場合

import WebKit

class ViewController: UIViewController {
var webView: WKWebView!

// MARK:- WebView Configure
override func loadView() {
    let webConfig = WKWebViewConfiguration()
    webView = WKWebView(frame: .zero, configuration: webConfig)
    view = webView
}


override func viewDidLoad() {
    super.viewDidLoad()
    // call urlrequest fun
    loadURLRequest()
}

//MARK:- Webview URLRequest
func loadURLRequest()  {
    let urlString = "https://www.google.com"
    let url = URL(string: urlString)
    let urlRequest = URLRequest(url: url!)
    webView.load(urlRequest)
}
}

//目的Cの場合

#import <WebKit/WebKit.h>

@interface ViewController ()<WKNavigationDelegate,WKUIDelegate>{
WKWebView *webView;
}

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
    
NSURL *url = [[NSURL alloc] initWithString: @"https://www.google.com"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
    [webView loadRequest: request];
}


- (void)loadView {
[super loadView];

WKWebViewConfiguration *configu = [[WKWebViewConfiguration alloc] init];
webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configu];
webView.UIDelegate = self;
self.view = webView;
}

@end

ここに画像の説明を入力してください


0

これはカンパイの回答に対するコメントであるべきですが、コメントするのに十分な評判ポイントがありません。

明示的なiOSバージョンに加えて、[ファイルインスペクター]の[ビルド対象]ドロップダウンには、展開ターゲット(..)オプションも含まれています。可能な場合はバージョンを1か所で管理し、ビルドターゲットを変更したいと考えています。一般設定の対応するエントリを11.0に変更しましたが、まだ展開ターゲット(9.3)と表示されていましたが、完全に混乱しました。

すべてを期待どおりに機能させるにはXCode(11.3.1)の再起動が必要でした。オプション 'Deployment Target(11.0)'が利用可能でした(9.3はなくなりました)。選択後、すべてが期待どおりに機能しました。


0
import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {
    
    @IBOutlet weak var webViewContainer: UIView!
    private var webView: WKWebView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        addWebView()
        
        let myURL = URL(string: "https://www.apple.com")
        if let myURL = myURL {
            let myRequest = URLRequest(url: myURL)
            webView?.load(myRequest)
        }
    }
    
    private func addWebView() {
        let webConfiguration = WKWebViewConfiguration()
        let size = CGSize.init(width: 0.0, height: self.webViewContainer.frame.size.height)
        let customFrame = CGRect.init(origin: CGPoint.zero, size: size)
        self.webView = WKWebView (frame: customFrame, configuration: webConfiguration)
        if let webView = self.webView {
            webView.translatesAutoresizingMaskIntoConstraints = false
            self.webViewContainer.addSubview(webView)
            webView.topAnchor.constraint(equalTo: webViewContainer.topAnchor).isActive = true
            webView.rightAnchor.constraint(equalTo: webViewContainer.rightAnchor).isActive = true
            webView.leftAnchor.constraint(equalTo: webViewContainer.leftAnchor).isActive = true
            webView.bottomAnchor.constraint(equalTo: webViewContainer.bottomAnchor).isActive = true
            webView.heightAnchor.constraint(equalTo: webViewContainer.heightAnchor).isActive = true
            webView.uiDelegate = self
        }
    }
}

-5

UIWebViewはiOS11で非推奨になり、WKWebViewはiOS11でのみ機能します-これはXcode GMのバグのように聞こえます。


うん。以前のバージョンのiOSにデプロイする場合に見つけた唯一の回避策は、プログラムでWKWebViewを追加することです。
Mehdi Chennoufi、2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.