Xcode 9 GM - WKWebView NSCoding support was broken

2020-01-25 04:39发布

问题:

Does anyone know how to fix this error with Xcode 9 GM? I'm working on an app made with Xcode 8.3, the deployment target is for iOS 9.3 and I never had this problem before. I don't find any information here or on Apple forums yet :(

Edit: This error came when I put a WKWebView into interface builder, not if I use it programmatically.

Edit 2: Well, it's finally not a bug, see Quinn's answer below to have more information about this behavior. Thanks to him for the explanation.

回答1:

The error is correct behavior, and not a bug in Xcode 9. Although WKWebView was introduced in iOS 8, there was a bug in -[WKWebView initWithCoder:] that was only fixed in iOS 11, which always crashed at runtime and thus prevented configuring one within Interface Builder.

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

Rather than allow developers to build something in IB that would be broken at runtime, it is a build error. It's an inconvenient limitation since iOS 11 was only recently released, but there's really no other good option.

The workaround for older deployment targets is to continue to add the WKWebView in code, as @fahad-ashraf already described in his answer:

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



回答2:

This seems to be a bug in Xcode 9 and was also present in the betas. You will only get the build error if you are creating a WKWebView through the storyboard. If you progmatically create the WKWebView in the corresponding ViewController class file, you should be able to build on iOS versions below iOS 11. Here is the approach given on Apple's website for how to accomplish this:

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)
    }}

You should then be able to implement WKWebView functionality as you normally would.

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



回答3:

If you want to realize a custom UIViewController with other components in addition you can make a "container" through the storyboard called for example 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)
    }


回答4:

If you are moved from older target to iOS 11.0 and still you are getting this error, then use below solution.

  1. Go to Storyboard (Main.storyboard), click on any Scene.
  2. Select 'File Inspector' which is the right side property window of Xcode
  3. Change 'Builds for' value to 'iOS 11.0 and Later'
  4. Compile and Build



回答5:

I have faced the same issue but it can be tackle if we add WKWebView programmatically.

  1. Do whatever design you want to make in storyboard but leave the room for WKWebView, in that area drag & drop a view and name it as webViewContainer and declare these two properties,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
    
  2. Now create and add webView like this:

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

    createWebView function is declared as,

    -(WKWebView *)createWebView
    {
         WKWebViewConfiguration *configuration = 
                   [[WKWebViewConfiguration alloc] init];
         return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
    
  3. Now add this newly created webView to your containerView, like this, :

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
    
  4. Finally, just load your Url like this,

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

Thanks for reading this.



回答6:

WebKit was introduced in iOS 8 but it was released with an error which caused in a runtime crash, If you are using Xcode 9/10, your project configuration support less than iOS 11 and if you are trying to add WKWebView using interface builder. Xcode immediately shows a compile-time error.

WKWebView before iOS 11.0 (NSCoding Support was broken in the previous version)

Although WKWebView was introduced in iOS 8, there was a bug in –[WKWebView initWithCoder:] that was only fixed in iOS 11.

Resolution is you must add WKWebView through code (Only if you are supporting below iOS 11). That actually sounds strange.

Another solution is to change the Interface Builder Document Builds for the option to iOS 11 and later (If you’re migrating from older target to iOS 11 and still getting the same error).



回答7:

I got this problem too,but when I set development target to 11.0,the project can run but the error still there.



回答8:

UIWebView is deprecated in iOS11 and WKWebView works only in iOS11 - this sounds like a bug in Xcode GM.